Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android PopupMenu

Android PopupMenu

編輯:關於Android編程

 

 

彈出菜單是停靠在一個View上的一個模式菜單。如果View對象下方有空間,那麼彈出菜單將顯示在停靠對象的下方,否則會顯示在上方。這是非常有用的:
1.  給指定內容的操作提供一個溢出式菜單(如圖4所示的Gmail的郵件頭)。

 

圖4. Gmail應用中的一個彈出菜單,停靠於右上角的溢出按鈕。

注意:這是跟上下文菜單不一樣,上下文菜單是對選擇內容有影響的操作。針對應用選擇內容的操作,請使用上下文操作模式或浮動內容菜單。

2.  提供命令語句的第二部分(如一個標記為“Add”按鈕,用彈出菜單來產生不同的“Add”選項)。

3.  提供一個不保留持久選擇的類似Spinner組件的下拉菜單。

注意:彈出菜單是在API 級別 11和更高版本上才有效的。

如果你在XML中定義了你的菜單,以下是如何顯示彈出菜單的方法:

1.  用它的構造器實例化一個PopupMenu對象,它需要當前應用程序的Context和菜單要停靠的那個View兩個對象作為參數。

2.  使用MenuInflater對象把你的菜單資源裝載到由PopupMenu.getMenu()方法返回的Menu對象中。在API 級別 14以上的版本,你能夠使用PopupMenu.inflate()方法來替代。

3.  調用PopupMenu.show()方法來顯示彈出菜單。

例如,下列是一個帶有android:onClick屬性的按鈕顯示彈出菜單的方法:

清單文件中的定義:

<ImageButton
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/ic_overflow_holo_dark"
    android:contentDescription="@string/descr_overflow_button"
    android:onClick="showPopup" />

Activity中的代碼:

public void showPopup(View v) {
    PopupMenu popup = new PopupMenu(this, v);
    MenuInflater inflater = popup.getMenuInflater();
    inflater.inflate(R.menu.actions, popup.getMenu());
    popup.show();
}

在API 級別 14和更高的版本上,你能夠用PopupMenu.inflate()方法把填充菜單的兩個代碼合並到一起。

當用戶選擇了一個菜單項或在觸摸了菜單區域的外部,這個菜單就會消失。你能使用PopupMenu.OnDismissListener回調方法來監聽菜單消失事件。

處理點擊事件

當用戶選擇一個菜單項來執行一個操作時,你必須要實現PopupMenu.OnMenuItemClickListener接口並且通過調用 setOnMenuItemClickListener()方法把它注冊給你的PopupMenu對象。當用戶選擇一個項目是,系統會調用你的接口中的 onMenuItemClick()回調方法。如:

public void showMenu(View v) {
    PopupMenu popup = new PopupMenu(this, v);

    // This activity implements OnMenuItemClickListener
    popup.setOnMenuItemClickListener(this);
    popup.inflate(R.menu.actions);
    popup.show();
}

@Override
public boolean onMenuItemClick(MenuItem item) {
    switch (item.getItemId()) {
        case R.id.archive:
            archive(item);
            return true;
        case R.id.delete:
            delete(item);
            return true;
        default:
            return false;
    }
}

創建菜單組

菜單組是共享某些特性的菜單項目的集合,使用菜單組,可以做以下事情:

1.   用setGroupVisible()方法顯示或隱藏組內的所有菜單項;

2.   用setGroupEnabled()方法啟用或禁用組內的所有菜單項;

3.   用setGroupCheckable()方法指定所有組內項目是否可復選。

你能夠通過把菜單資源中<item>元素嵌套進<group>元素中來創建分組菜單,或者使用帶有分組ID的add()方法。

以下是包含了一個分組的菜單資源

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/menu_save"
          android:icon="@drawable/menu_save"
          android:title="@string/menu_save" />
    <!-- menu group -->
    <group android:id="@+id/group_delete">
        <item android:id="@+id/menu_archive"
              android:title="@string/menu_archive" />
        <item android:id="@+id/menu_delete"
              android:title="@string/menu_delete" />
    </group>
</menu>

這個分組菜單中的項目與第一個項目顯示在同一個層次級別上---菜單中的三個項目是同級的,你能夠使用上面列出的方法,通過引用組ID來修改分組菜單中兩個項目的屬性。系統也不會把分組的菜單項給分開。如,如果你給每個菜單項聲明了android:showAsAction=”ifRoom”屬性,那麼它們將既可以同時顯示在操作欄中,也可以同時顯示在操作溢出中。

使用可復選的菜單項

菜單能夠用於切換選項的界面,針對一個獨立的選項使用一個可復選的Checkbox菜單,對於一組互斥的選項可使用一組帶有單選按鈕的菜單(如圖5所示)。

 

圖5.帶有復選菜單項的子菜單截圖。

注意:圖標菜單(選項類型的菜單)中的菜單項不能顯示一個復選框或單選按鈕。如果你選擇了讓圖標菜單中的菜單項可復選,那麼就必須在每次狀態改變時通過更換手動的更換圖標或文本來的指明復選的狀態。

你能夠使用<item>元素中的android:checkable屬性給單獨的菜單項定義可復選的行為,或者用<group> 元素中的android:checkableBehavior屬性給一組菜單項定義可復選行為。如,下例中菜單組中的每個菜單項都帶有一個可復選的復選按鈕:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <group android:checkableBehavior="single">
        <item android:id="@+id/red"
              android:title="@string/red" />
        <item android:id="@+id/blue"
              android:title="@string/blue" />
    </group>
</menu>

android:checkableBehavior屬性可以有以下三種設置:

1.  single:菜單組中僅有一個菜單能夠被復選(復選按鈕)

2.  all:所有菜單項都能夠被復選(復選框)

3.  none:沒有項目是可復選的

你能夠在<item>元素中使用android:checked屬性給一個菜單項設置默認的復選狀態,並且可以用setChecked()方法在代碼中改變它。

當一個可復選的菜單項被選擇的時候,系統會調用對應被選擇的菜單項的回調方法(如onOptionsItemSelected())。你必須在這時設置復選框的狀態,因為復選框或復選按鈕不會自動的改變它們的狀態。你能夠用isChecked()方法來查詢復選菜單的當前狀態(被用戶選擇之前的狀態),然後用setChecked()方法設置復選狀態。如:

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case R.id.vibrate:
        case R.id.dont_vibrate:
            if (item.isChecked()) item.setChecked(false);
            else item.setChecked(true);
            return true;
        default:
            return super.onOptionsItemSelected(item);
    }
}

如果不用這種方式設置復選狀態,那麼當用戶選擇菜單項(復選框或復選按鈕)的時候,它的可視狀態將不會發生改變。在你設置這個狀態時,Activity會保留菜單的狀態,以便用戶隨後打開這個菜單時,讓你設置的復選狀態可見。

注意:可復選菜單項打算僅在每個會話的基礎上使用,並且在應用銷毀之後不保存復選狀態。如果你的應用打算保存用戶的設置,你應該使用共享的方式來保存數據。

基於Intent對象來添加菜單項

有些時候,你想要菜單項使用一個Intent對象來啟動一個Activity(不管這個Activity是你的應用程序中的還是其他應用程序中的)。

當你知道你要使用的Intent對象,並且也指定了啟動這個Intent對象的菜單項時,你就能夠在對應的on-item-selected回調方法(如 onOptionsItemSelected()回調方法)調用期間用startActivity()方法執行這個Intent對象。

但是,如果你不確定用戶設備上是否包含了處理這個Intent對象的應用程序,那麼添加調用這個Intent對象的菜單項就有可能導致一個非功能性菜單的產生,因為可能沒有接受這個Intent對象的Activity。要解決這個問題,Android能夠讓你在設備上查找處理你的Intent對象的 Activity時,動態的把菜單項添加到菜單中。

以下是在能夠接受Intent對象的有效的Activity基礎上來添加菜單項的方法:

1.  用CATEGORY_ALTERNATIVE或CATEGORY_SELECTED_ALTERNATIVE分類,再加上一些其他的要求,定義一個Intent對象。

2.  調用Menu.addIntentOptions()方法,Android會搜索系統中能夠接受這個Intent對象的任何應用程序,並把它們添加到你的菜單中。

如果沒有安裝能夠滿足Intent要求的應用程序,那麼就不會添加菜單項。

注意:CATEGORY_SELECTED_ALTERNATIVE被用於處理屏幕上當前被選擇的元素。因此,應該只在用onCreateContextMenu()方法創建菜單時使用這個分類。

如:

@Override
public boolean onCreateOptionsMenu(Menu menu){
    super.onCreateOptionsMenu(menu);

    // Create an Intent that describes the requirements to fulfill, to be included
    // in our menu. The offering app must include a category value of Intent.CATEGORY_ALTERNATIVE.
    Intent intent = new Intent(null, dataUri);
    intent.addCategory(Intent.CATEGORY_ALTERNATIVE);

    // Search and populate the menu with acceptable offering applications.
    menu.addIntentOptions(
         R.id.intent_group,  // Menu group to which new items will be added
         0,      // Unique item ID (none)
         0,      // Order for the items (none)
         this.getComponentName(),   // The current activity name
         null,   // Specific items to place first (none)
         intent, // Intent created above that describes our requirements
         0,      // Additional flags to control items (none)
         null);  // Array of MenuItems that correlate to specific items (none)

    return true;
}

對於找到的每個提供了跟定義的Intent對象匹配的Intent過濾器的Activity,都會添加一個菜單項,這個菜單項使用Intent過濾器的 android:label的屬性值做為菜單項的標題、應用程序的圖標做為菜單項的圖標。addIntentOptions()方法返回被添加的菜單的個數。

注意:當你調用addIntentOptions()方法時,它會覆蓋在第一個參數中指定的菜單組的所有菜單項。

允許你的Activity被添加給其他菜單

你也能夠包Activity的服務提供給其他的應用程序,以便你的應用能夠包含在其他應用的菜單中。

要想在其他的應用程序菜單中包含你的應用程序,你需要向通常那樣定義一個Intent過濾器,但要確認包括CATEGORY_ALTERNATIVE或CATEGORY_SELECTED_ALTERNATIVE分類,如:

<intent-filter label="@string/resize_image">
    ...
    <category android:name="android.intent.category.ALTERNATIVE" />
    <category android:name="android.intent.category.SELECTED_ALTERNATIVE" />
    ...
</intent-filter>

 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved