情境
如果想要在任意畫面掛上Toolbar, 其實是可行的, 只是在操作Menu跟如何使用Menu不太相同。
完整程式碼
如果有需要完整程式碼,可以到 GitHub 下載或觀看。
這邊示範使用 Dialog 掛上 Toolber 並且操作 Menu,一開始主程式宣告一個Button點下去會跳出Dialog。
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
show_dialog.setOnClickListener { MyDialog(this@MainActivity).show() }
}
}
宣告 MyDialog 繼承 Dialog。
class MyDialog(private val mContext: Context) : Dialog(mContext) {
init {
setContentView(R.layout.my_dialog)
toolbar.title = "Toolbar Demo"
}
}
改一下Theme
class MyDialog(private val mContext: Context) : Dialog(mContext, R.style.MyDialogTheme) {
init {
setContentView(R.layout.my_dialog)
toolbar.title = "Toolbar Demo"
}
}
可以從上面看到吃了一個MyDialogTheme。
<style name="MyDialogTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="colorPrimary">#AA92ef</item>
<item name="colorPrimaryDark">#7868F3</item>
<item name="colorAccent">#FFF001</item>
</style>
你可以從Android Studio上面看到一些顏色的資訊。
接著我們塞入Toolbar。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:minHeight="?attr/actionBarSize" />
</LinearLayout>
看效果。
讓我們來設計一個back按鈕, 可以透過Android Studio的Vector工具建立一個向量圖。
流程如下:
- 對res點選右鍵->選擇New->選擇Vector Asset
跳出視窗可以選擇內建的icon
可以看到有很多內建的SVG圖, 可以參考Android — 讓APK裡的切圖容量減少95%的好方法
讓我們選擇 " < " 這個符號
就會產生一個xml檔案
可以看到它其實是用xml所寫成的一個向量檔案
但是我們希望是白色的,因此,修改一下數值。
接著從 Dialog 去控制 back 按鈕。
class MyDialog(private val mContext: Context) : Dialog(mContext, R.style.MyDialogTheme) {
init {
setContentView(R.layout.my_dialog)
toolbar.title = "Toolbar Demo"
toolbar.setNavigationIcon(R.drawable.ic_keyboard_arrow_left_24dp)
toolbar.setNavigationOnClickListener { dismiss() }
toolbar.inflateMenu(R.menu.menu_layout)
}
}
可以看到我們加了 Title 的文字跟設定 Navigation 的 Icon,直接看效果。
字體是黑色的,而且返回鍵(<
)大小好像不是符合我們需求,稍微改一下,將向量圖的 xml 大小改成 48 * 48。
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="48dp"
android:height="48dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
</vector>
改了大小變得比較正常,但是字體還是黑色的。
因此我們回到 Dialog 的 theme 那邊加入一行程式碼。
<style name="MyDialogTheme" parent="Theme.AppCompat.Light.NoActionBar">
//..
<item name="titleTextColor">@android:color/white</item>
</style>
這樣就可以看到顯示是正常的了!
那如果我們想要按下就關閉 Dialog,其實只要對 Toolbar 設定事件就可以了。
toolbar.setNavigationOnClickListener { dismiss() }
這樣就完成呼叫 Dialog 跟關閉 Dialog 的功能了。
那怎麼呈現 Menu 呢?
首先建立一個 menu_layout.xml
在 menu 資料夾內,從官網可以得知,app:showAsAction="always"
代表總是呈現在 Toolbar 上面。
<?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
app:showAsAction="always"
android:title="@string/edit"
android:id="@+id/menu_edit"
/>
</menu>
然後在Dialog頁面寫下以下程式碼。
mToolbar.inflateMenu(R.menu.menu_layout)
這樣就完成一個簡單的 Menu 嗎? 事情不會總是那麼順利。
發現字型太小且顏色不對,因此,必須修改一下Theme。
<style name="MyDialogTheme" parent="Theme.AppCompat.Light.NoActionBar">
//...
<item name="actionMenuTextColor">@android:color/white</item>
<item name="actionMenuTextAppearance">@style/toolbar_menu_edit</item>
</style>
<style name="toolbar_menu_edit">
<item name="android:textSize">16sp</item>
</style>
調整 Menu Text 顏色跟大小, 看一下結果。
那如果要偵測按下去的事件怎麼辦?
toolbar.setOnMenuItemClickListener{
when (it.itemId) {
R.id.menu_edit -> Toast.makeText(mContext, "Edit is clicked!", Toast.LENGTH_SHORT).show()
}
false
}
跟一般設定事件差不多。