Photo by Caspar Camille Rubin on Unsplash
Android 的 Menu 選單有好幾種,如 ContextMenu、OptionMenu、PopupMenu等,其中 OptionMenu 選項菜單,是透過手機/平板上的 Menu 鍵來啟動(現在的手機/平板大部分都已經取消 Menu 鍵),本篇就來瞭解與實作 ContextMenu。ContextMenu 稱做快顯功能表或上下文功能表,也是一個浮動的菜單選項,類似 Windows 或 Linux 作業系統中,按下滑鼠右鍵的選單。在手機/平板由於沒有右鍵,當使用者在某個元件執行長按或單擊時出現 ContextMenu,這樣的方式不會影響畫面的框架與操作。
[建立 menu 功能表資源檔]
要製作 menu 功能表,需先將功能選項定義在功能表資源檔中,需先在 res 目錄內建立一個 menu 目錄,再建立一個功能表的選單的 XML 檔案,操作的畫面如下:(1) 首先在 Android Studio 的畫面,對左方的 res 目錄按右鍵,選擇「New」→「Directory」,再輸入目錄名稱為:menu。
(2) 在 menu 目錄按右鍵 → 「New」→「Menu Resource File」
(3) 接著輸入 menu 的 XML 檔檔名。
這樣就完成 XML 檔案的建立,建立的功能表會放置在 res\menu 目錄下。接著要在 XML 檔案中建立選單項目,使用<item></item>標記來建立,一個 menu 檔案中,可以有多個 item 作為選單項目的內容,並可在 item 標記內設置不同屬性,如功能表項目名稱、標題等內容。語法格式如下:
<item android:屬性 = "值"> </item>其他有關標記 item 常用的屬性如下表:
| XML屬性 | 說明 | 
|---|---|
| id | 設定功能表項目名稱為唯一標識設置ID。 | 
| title | 設定功能表標題。 | 
| alphabeticShortcut | 為功能表項目指定字元快速鍵。 | 
| numericShortcut | 為功能表項目指定數位快速鍵。 | 
| icon | 設定功能表項目圖示。 | 
| enabled | 設定功能表項目是否可用。 | 
| checkable | 設定功能表項目是否可選。 | 
| checked | 功能表項目是否已選中。 | 
| visible | 設定功能表項目是否可見。 | 
若要建立子選單(Submenu),可以在 <item>與 </item>之間再建立一個 <menu></menu>的語法,新增加的 menu 標記中,再增加 item 的標記,如下範例,在「檔案」選項下,再建立兩個子選項「存檔」和「另存為...」。:
    <item
        android:id="@+id/m3"
        android:title="檔案">
        <menu xmlns:android= "http://schemas.android.com/apk/res/android" >
            <item  android:id= "@+id/save"
                android:title= "存檔"  />
            <item  android:id= "@+id/save_as"
                android:title= "另存為..."  />
        </menu>
    </item>
    
[ContextMenu]
當使用者對元件長按時,彈出的功能表就是 ContextMenu 快顯功能表,如要使用快顯功能表,需先依照上述步驟在資源的功能表目錄內,建立一個 XML 功能表描述檔,接著就要在 java 目錄內找到對應的 MainActivity.java 主程式,進行以下幾個方法的重新定義:(1) 在 Activity 的 onCreate() 方法中使用 registerForContextMenu() 方法註冊 ContextMenu。
例如為文字方塊元件註冊上下文功能表,當長按該文字方塊時,出現快顯功能表,可以使用以下程式:
TextView tv=(TextView)findViewById(R.id.show); registerForContextMenu(tv); //為文字框註冊快顯功能表
(2) 在 MainActivity 中重寫 onCreateContextMenu() 方法。
先建立一個用於解析功能表資源檔的 MenuInflater 物件,然後再使用 inflate() 方法解析一個功能表資源檔,並將解析後的功能表保存在 menu 中,可使用 menu 相關的方法,如設定選單表頭可使用 setHeaderTitle() 方法進行設定,程式碼如下:
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
        MenuInflater inflater = new MenuInflater(this);   //產生一個 MenuInflater物件
        inflater.inflate(R.menu.cm_menu, menu);   //解析 menu 選單檔
        menu.setHeaderTitle("請選擇:");     //為選單表頭設置標題
    }
(3) 在 MainActivity 中重寫 onContextItemSelected() 方法,當功能表項目被選擇時,可做出相對應的處理。
例如當功能表項目被選擇時,使用 Toast 顯示一串訊息文字,程式如下:
    public boolean onContextItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.m1:   //在 menu 功能表定義的第一個 item 的名稱
                Toast.makeText(this, "您按下了「關於」...", Toast.LENGTH_LONG).show();
                break;
            case R.id.m2:
                finish();
        }
        return super.onContextItemSelected(item);   // 傳回值
    }
[程式範例]
(1)新建一個模組 Module,在 res 目錄下新增一個 menu 目錄,目錄內建立 menu.xml 檔案,定義內容如下:<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/m1"
        android:title="關於快顯功能表選單" />
    <item
        android:id="@+id/m2"
        android:title="結束 APP" />
</menu>
(2) 進入 res/layout 目錄下點選佈局檔 activity_main.xml。將預設的內容刪除,建立 1 個 TextView 文字框,以下是完整 XML 的內容。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/layout1"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        android:id="@+id/tv1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="100sp"
        android:textSize="26sp"
        android:text="長按這裡測試快顯功能表。" />
</RelativeLayout>
(3)在 MainActivity.java 在 onCreate() 方法內,先建立與佈局檔的物件,用 findValueById 連結 TextView 元件,改寫 onCreateContextMenu 取得表單,重寫 onContextItemSelected 根據 item 的 ID 名稱判斷按下的選項,使用 Toast 顯示在畫面上或結束程序。程式碼如下:
package com.example.mycontextmenu;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.ContextMenu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
public class cm_MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_cm_main);
        TextView tv1 = (TextView) findViewById(R.id.tv1);
        registerForContextMenu(tv1);
        }
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
        MenuInflater inflater = new MenuInflater(this);   //產生一個 MenuInflater物件
        inflater.inflate(R.menu.cm_menu, menu);  //解析 menu 選單檔
        menu.setHeaderTitle("請選擇:");   //為菜單頭設置標題
    }
    public boolean onContextItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.m1:
                Toast.makeText(this, "您按下了「關於快顯功能表選單」...", Toast.LENGTH_LONG).show();
                break;
            case R.id.m2:
                finish();
        }
        return super.onContextItemSelected(item);
    }
}
執行的結果如下:
[參考資料]
- Developer : ContextMenu
 - 明日科技:Android 從入門到精通
 





張貼留言