如何在Toolbar使用Menu(kotlin)

如何在Toolbar使用Menu(kotlin)

情境

如果想要在任意畫面掛上Toolbar, 其實是可行的, 只是在操作Menu跟如何使用Menu不太相同。

完整程式碼

如果有需要完整程式碼,可以到 GitHub 下載或觀看。

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  
}

跟一般設定事件差不多。