第14章 應用欄
應用欄菜單
在 Xml 文件中定義菜單
- 先定義 String 字符串資源,作爲菜單項的名稱
代碼清單:res/values/strings.xml
<resources>
...
<string name="new_crime">New Crime</string>
</resources>
- 添加菜單xml文件
右鍵res目錄,選擇【New -> Android resource file】,
菜單定義文件要遵循與佈局文件一樣的命名原則
點擊【OK】後,自動生成菜單xml文件,
代碼清單:res/menu/fragment_crime_list
<menu xmlns:android="http://schemas.android.com/apk/res/android"
</menu>
爲菜單定義文件添加菜單項:
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" >
<item android:id="@+id/new_crime"
android:icon="@android:drawable/ic_menu_add"
android:title="@string/new_crime"
app:showAsAction="ifRoom|withText"/>
</menu>
- @+id/new_crime 是菜單的Id,後面需要Id來確認點擊的是哪個菜單項
創建 Fragment 菜單
class CrimeListFragment : Fragment() {
...
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setHasOptionsMenu(true)
}
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
super.onCreateOptionsMenu(menu, inflater)
inflater.inflate(R.menu.fragment_crime_list, menu)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
return when (item.itemId) {
R.id.new_crime -> {
var crime = Crime()
crimeListViewModel.addCrime(crime)
callbacks?.onCrimeSelected(crime.id)
true
}else -> return super.onOptionsItemSelected(item)
}
}
}
- setHasOptionsMenu(true): Activity中的菜單的onCreateOptionsMenu()方法是有Android操作系統回調,
而 Fragment的菜單的onCreateOptionsMenu()方法是由FragmentManager回調,故需要以下代碼讓FragmentManager知道需要調用
Fragment的菜單的onCreateOptionsMenu()的方法
setHasOptionsMenu(true)
- onCreateOptionsMenu : 使用菜單文件填充菜單
- onOptionsItemSelected:響應選擇菜單選項事件
- 默認返回 父類的 return super.onOptionsItemSelected(item)
使用 Android Asset Studio
爲 Action Bar 的菜單添加自定義圖標
右鍵點擊 res/drawable 目錄,選擇 New -> ImageAsset 菜單項,彈出Asset Studio
Ion Type:選擇 Action Bar and Tab Icons
Name: ic_menu_add
選擇一個 add 的圖標
點擊【OK】,【Next】按鈕,
Asset Studio 會生成hdpi、xxhdpi等類型的圖標
點擊 Finsh按鈕,生成的圖標資源
修改菜單的佈局文件,引用新的圖標
代碼清單:res/menu/fragment_crime_list.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" >
<item android:id="@+id/new_crime"
android:icon="@drawable/ic_menu_add"
android:title="@string/new_crime"
app:showAsAction="ifRoom|withText"/>
</menu>
新的菜單項圖標效果:
圖標是黑色的,把剛纔的圖標刪除,重複上述步驟,在下面這一步,選擇黑色主題,這樣圖標的顏色就是白色,在黑色主題上就能看得見白色圖標了
重啓編譯,運行設備
應用欄、ActionBar(操作欄)、Tool Bar(工具欄)
Android 5.0(API 21) 開始,應用欄都是優先使用新引入的 ToolBar 類來實現的
ActionBar(操作欄)的限制很多:整個應用程序只能配置一個操作欄,並且位置和尺寸必須固定(位於屏幕頂部)
ToolBar(工具欄)就沒有這個限制:每個activity 、Fragment 都可以有自己獨立的應用欄,位置任意
AppCompat版應用欄
AppCompat版應用欄使用 Jetpack版的Toobar來實現。
要使用 AppCompat版應用欄,引入 AppCompatActivity的 supportFragmentManager的屬性:
val appCompatActivity = this as AppCompatActivity
val appBar = appCompatActivity.supportActionBar as Toolbar
但是就目前創建默認項目來看,查看主題文件
/res/values/themes/themes.xml
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="Theme.CriminalIntent" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
<item>....
</style>
</resources>
從主題:Theme.MaterialComponents.DayNight.DarkActionBar 來看,用的是 ActionBar,如果直接在代碼中強行轉換爲 Toolbar 是會拋出異常的。
要應用 ToolBar 還是得查閱下資料。
引用到AppCompat版應用欄,就可以做一些應用欄設置,比如:設置標題:
appBar.setTitle(R.string.crime_list_title)