簡要
AppBar應用欄,提供固定的位置,用於顯示當前屏幕與操作
Activity擁有應用欄:Fragment變更/擴充菜單,用途每個介面皆需要應用欄,但Fragment的應用欄選項皆不同時,可以有效的讓各個介面有更好的規劃
Fragment擁有應用欄:大部分皆不需要應用欄,只有特定的Fragment需要時,會採用此方法
Menu的一些設置參考Android Menu showAsAction屬性
由ActionBar更換Toolbar,以及Toolbar一些設置參考Android ActionBar與Toolbar
以下分成幾個區塊介紹
- Activity擁有應用欄
- Fragment擁有應用欄
- 動態修改Menu是否顯示
- Menu點擊事件處理
1. Activity擁有應用欄
了解Menu基本的設定後,建立好的Menu該如何設定呢?
Activity擁有應用欄,意味著Activity與Fragment皆有Menu且是用共的,因為Activity擁有
用途:每個介面皆需要應用欄,但Fragment的應用欄選項皆不同時
首先先幫Activity與Fragment建立一個不一樣的Menu,方便觀察效果
Activity Menu如下
<?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/searchMenu" app:actionViewClass="android.widget.SearchView" android:icon="@drawable/ic_baseline_search_24" android:title="search" app:showAsAction="ifRoom|collapseActionView" /> <item android:id="@+id/testMenu" android:icon="@drawable/ic_baseline_fast_forward_24" android:title="test2" app:showAsAction="ifRoom"/> </menu>
Fragment Menu如下
<?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/backButton"
android:icon="@drawable/ic_baseline_chevron_left_24"
app:showAsAction="ifRoom"
android:title="test1"/>
<item android:id="@+id/testMenu2"
android:icon="@drawable/ic_baseline_favorite_24"
app:showAsAction="ifRoom"
android:title="test2"/>
</menu>
建立完後
Activity中新增下列程式碼
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
menuInflater.inflate(R.menu.activity_menu, menu)
return true
}
Fragment中新增以下程式碼
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
inflater.inflate(R.menu.fragment_menu, menu)
//切換到這個Fragment時,不需要使用searchMenu
menu.findItem(R.id.searchMenu).isVisible = false
}
在Fragment onCreated中新增,向Activity註冊使用
setHasOptionsMenu(true)
這樣在這個Fragment時,就有專屬的Menu選項,其他的頁面,皆顯示Activity的Menu


2. Fragment擁有應用欄
用途:大部分皆不需要應用欄,只有特定的Fragment需要時,會採用此方法
首先先把Activity的ActionBar隱藏
supportActionBar?.hide() binding.mToolbar.visibility = View.GONE
隱藏後在Fragment的Layout新建
<androidx.appcompat.widget.Toolbar
android:id="@+id/mToolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:elevation="4dp"
app:layout_constraintVertical_bias="0"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent">
<TextView
android:id="@+id/titleTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="title"
android:textSize="20dp"
android:textColor="@color/white"
android:layout_gravity="center"/>
</androidx.appcompat.widget.Toolbar>
接著在onViewCreated裡面新增下列程式碼,這樣就新增好Menu了
binding.mToolbar.inflateMenu(R.menu.fragment_menu)
如果要更換Menu方式也很簡單
這裡設定一個Button按下時變更Menu
binding.replaceMenuBtn.setOnClickListener { clearToolbarMenu() if(!isChangeMenu) { binding.mToolbar.inflateMenu(R.menu.activity_menu) } else { binding.mToolbar.inflateMenu(R.menu.fragment_menu) } isChangeMenu = !isChangeMenu } private fun clearToolbarMenu() { binding.mToolbar.menu.clear() }
3. 動態修改Menu是否顯示
這裡分為兩部分
a. Activity擁有應用欄
在Fragment中,新增以下程式碼
private var isEditMenu = false override fun onPrepareOptionsMenu(menu: Menu) { super.onPrepareOptionsMenu(menu) val item = menu.findItem(R.id.backButton) item.isVisible = isEditMenu }
並設定一個Button,按下時,顯示/隱藏Menu
binding.replaceMenuBtn.setOnClickListener { isEditMenu = !isEditMenu requireActivity().invalidateOptionsMenu() }
b. Fragment擁有應用欄
使用相對比較簡單一點,方式如下
在Fragment中,新增以下程式碼
private fun updateToolbar() { isEditMenu = !isEditMenu val saveItem = binding.mToolbar.menu.findItem(R.id.testMenu2) saveItem.isVisible = isEditMenu }
設定一個Button,按下時,顯示/隱藏Menu
binding.backBtn.setOnClickListener {
updateToolbar()
}
4. Menu點擊事件處理
這裡分為兩部分
a. Activity擁有應用欄
在Fragment裡面新增下列程式碼
override fun onOptionsItemSelected(item: MenuItem): Boolean {
return when(item.itemId) {
R.id.testMenu2 -> {
true
}
else -> {
super.onOptionsItemSelected(item)
}
}
}
如果是這個按鈕則攔截(設為true),否則不攔截給Activity處理(設為super.onOptionsItemSelected(item))
在Activity中新增下列程式碼
override fun onOptionsItemSelected(item: MenuItem): Boolean { return when(item.itemId) { R.id.searchMenu -> { true } R.id.testMenu -> { true } R.id.testMenu2 -> { true } else -> super.onOptionsItemSelected(item) } }
這樣設定完後,Fragment沒攔截的按鈕就可以在Activity中操作
b. Fragment擁有應用欄
監聽的方式與Activity擁有應用欄不太一樣,使用方式如下
binding.mToolbar.setOnMenuItemClickListener {
when(it.itemId) {
R.id.testMenu2 -> {
println("test")
true
}
else -> false
}
}
以上內容參考Android 官網
相關文章
Android Menu showAsAction屬性 | Android ActionBar與Toolbar |
1. 簡要 2. Menu的showAsAction屬性介紹 | 簡要 1. 如何將預設ActionBar關閉,改用Toolbar呢? 2. Toolbar Title如何置中呢? 3. 為Toolbar設定Menu |