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 從入門到精通





張貼留言