Android Menus II-Popup Menu和Menu Groups

来源:互联网 发布:网络金融理财产品 编辑:程序博客网 时间:2024/06/06 05:46

概述:

Popup menu是挂靠在某一个View的菜单, 在点击View的时候可以弹出. 常见的应用场景有:

1.      未指定的内容指定一个弹出的菜单, 比如Gmail的弹出菜单:


相对于context menu, Popup menu并不影响选中的View. Contextmenu通常是对选中的View的操作.

2.      为某个操作提供更详细的操作.

3.      提供一个类似下拉菜单的操作.(好无聊..)

Popup menu只能用于API11及以上版本.

创建一个Popupmenu的步骤:

1.      实例化一个PopupMenu对象. 需要两个参数, 一个是Context, 另一个是需要悬靠的View. 它会在指定的View旁边出现.

2.      使用MenuInflater来加载菜单资源到PopupMenu.getMenu()返回的Menu对象中. 在API14及以上版本中我们可以使用PopupMenu.inflate()方法代替.

3.      调用PopupMenu.show()方法.

栗子, 首先创建一个button, Popup Menu响应这个button的点击事件:

<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中实现show:

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

Menu将会在用户点击某个item或者点击菜单外的区域的时候消失, 我们可以通过PopupMenu.OnDismissListener()方法来监听这一事件.

 

处理Popup Menu的点击事件:

跟所有的点击事件差不多, 我们需要通过监听器监听点击事件. 监听器是PopupMenu.OnMenuItemClickListener, 可以通过PopupMenu的setOnMenuItemclickListener()方法来设置这一事件. 当用户点击某个item,Android将会调用监听器的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;
    }
}

 

创建一个MenuGroups:

Menu Group是menu item的集合, 主要用于统一的管理, 在同一个Group中我们可以:

1.      显示或者不显示所有的item, 需要用到的方法是setGroupVisible().

2.      让所有的item可用或者不可用, 方法是setGroupEnabled().

3.      指定是否所有的item是可选择的, 方法是setGroupCheckable().

 

我们可以通过在XML文件中为<item>指定父标签<group>来将它们放在同一个Menu Group中, 还可以通过在代码中使用add()方法为item指定同一个group ID来将它们放入同一个Group, 这里是XML中的栗子:

<?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>

上面的三个item都是在同一级别的, 但是我们可以通过group统一操作后两个item. Android将总是一同处理同一group的item.

 

使用可选择的menu item:

Menu中可以使用单选框和复选框. 比如:


在options menu中的带图标的item不能显示选择框, 如果需要在这里添加选择框, 那么要手动指定选择状态.

我们可以在item里单独通过android:checkable属性指定这个<item>是否可以被选择. 也可以在group中通过android:checkableBehavior来指定. 这是一个通过group指定的栗子:

<?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>

在<group>的android:checkableBehavior属性中, 可以使用以下参数:

single:单选框.

all: 多选框.

none: 不可选.

我们可以在<item>中通过android:checked属性来指定选择框的默认选项, 然后可以在代码中通过setChecked()来更改它. 当一个可选择的item被选中的时候, Android会调用相应的回调方法(比如onOptionsItemSelected()), 我们必须在这里手动指定选择框的状态, 因为Android很懒, 没有为我们指定…我们可以使用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);
    }
}

如果不通过这种方法设置选择框的状态, 那么用户点击的时候就没反应. 这东西是基于会话的, 当我们的APP重新启动之后, 状态就没了, 我们应该使用SharedPreferences来保存状态.

 

通过Intent来为Menu增加Item:

有时候我们需要通过点击某个menu的item启动一个activity. 我们可以在item的点击事件中通过intent启动一个activity. 但是有时候我们并不知道这个intent是否可以成功的启动一个activity, 这时候就可能导致我们的某个item是没用的, 点击了, activity却没有启动. 为了解决这种情况, Android允许我们根据这个activity是否可以成功启动动态的添加menu的item, 如果Android发现这个activity无法启动, 那么就不会显示相关的item.

想要实现这个效果需要两个步骤:

1.      定义intent的时候指定CATEGORY_ALTERNATIVE和/或CATEGORY_SELECTED_ALTERNATIVE.

2.      调用Menu.addIntentOptions(). Android然后就会去查找是否有某个activity可以满足这个intent了.

如果没有activity符合这个intent, 那么menu就不会添加这个item.

CATEGORY_SELECTED_ALTERNATIVE只用来处理当前在屏幕上被选中的元素, 所以应该只用于在onCreateContextMenu()中创建Menu的时候使用.

栗子:

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

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

    // Search and populate the menu with acceptable offeringapplications.
    menu.addIntentOptions(
         R.id.intent_group,  // Menu group towhich new items will be added
         0,     // Unique item ID (none)
         0,     // Order for the items (none)
         this.getComponentName(),  // The currentactivity name
         null,  // Specificitems to place first (none)
         intent, // Intentcreated above that describes our requirements
         0,     // Additional flags to control items (none)
         null);  // Array ofMenuItems that correlate to specific items (none)

    return true;
}

对于每个可以匹配intent的activity, Android都会为Menu增加一个item. item的title会使用对应的intent filter的label属性. addIntentOptions()方法返回增加的item的个数. 当调用该方法的时候, 它会覆盖所有的menu item, 通过第一个参数指定menu group.

 

让我们的Activity可以出现在其它APP的Menu Item中:

除了在菜单中启动别的APP的Activity, 我们还可以让我们的Activity支持别人的APP的Menu. 想要实现这个功能只需要在我们的intent filter中加入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>

 


总结:

三种菜单:

Options menu: 最古老的菜单, 最开始由菜单按键触发, 在屏幕底部显示六个按钮,Android3.0之后改为在屏幕顶上显示, 通常用于Activity的全局操作, 比如搜索等. 创建方法: onCreateOptionsMenu().

 

Context menu: 上下文菜单, 菜单的操作跟选中的View有关, 可以用于单个的View也可以用于ListView,GridView等控件, 很常用. 创建方法: onCreateContextMenu().

 

Popup menu: 弹出菜单, 类似一个下拉菜单, 不关联View. 创建方法:PopupMenu.show().

 


参考: http://developer.android.com/guide/topics/ui/menus.html

 


0 0
原创粉丝点击