菜单总结

来源:互联网 发布:js prototype proto 编辑:程序博客网 时间:2024/05/16 09:08

三种菜单总结

一. 选项菜单:
选项菜单是某个 Activity 的主菜单项, 供您放置对应用产生全局影响的操作,如“搜索”、“撰写电子邮件”和“设置”。
这里写图片描述
如果您开发的应用适用于 Android 3.0(API 级别 11)及更高版本,则选项菜单中的项目将出现在应用栏中。 默认情况下,系统会将所有项目均放入操作溢出菜单中。用户可以使用应用栏右侧的操作溢出菜单图标(或者,通过按设备“菜单”按钮(如有))显示操作溢出菜单。 要支持快速访问重要操作,您可以将 android:showAsAction=”ifRoom” 添加到对应的 元素,从而将几个项目提升到应用栏中(如上图)。
1.向 Activity 添加工具栏
(1)确保 Activity 可以扩展 AppCompatActivity:
public class MyActivity extends AppCompatActivity {
// ...
}

(2)在应用清单中,将 元素设置为使用 appcompat 的其中一个 NoActionBar 主题。使用这些主题中的一个可以防止应用使用原生 ActionBar 类提供应用栏。例如:
<application
android:theme="@style/Theme.AppCompat.Light.NoActionBar"
/>

(3) 向 Activity 的布局添加一个 Toolbar。例如,以下布局代码可以添加一个 Toolbar 并赋予其浮动在 Activity 之上的外观:

<android.support.v7.widget.Toolbar   android:id="@+id/my_toolbar"   android:layout_width="match_parent"   android:layout_height="?attr/actionBarSize"   android:background="?attr/colorPrimary"   android:elevation="4dp"   android:theme="@style/ThemeOverlay.AppCompat.ActionBar"   app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>

4.在 Activity 的 onCreate() 方法中,调用 Activity 的 setSupportActionBar() 方法,然后传递 Activity 的工具栏。该方法会将工具栏设置为 Activity 的应用栏。例如:

@Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_my);    Toolbar myToolbar = (Toolbar) findViewById(R.id.my_toolbar);    setSupportActionBar(myToolbar);    }

5.为toolsbar添加功能:在res/menu/资源文件夹下添加一个xml布局

<menu xmlns:android="http://schemas.android.com/apk/res/android" >    <!-- "Mark Favorite", should appear as action button if possible -->    <item        android:id="@+id/action_favorite"        android:icon="@drawable/ic_favorite_black_48dp"        android:title="@string/action_favorite"        app:showAsAction="ifRoom"/>    <!-- Settings, should always be in the overflow -->    <item android:id="@+id/action_settings"          android:title="@string/action_settings"          app:showAsAction="never"/></menu>

6.添加操作事件

@Overridepublic boolean onOptionsItemSelected(MenuItem item) {    switch (item.getItemId()) {        case R.id.action_settings:            // User chose the "Settings" item, show the app settings UI...            return true;        case R.id.action_favorite:            // User chose the "Favorite" action, mark the current item            // as a favorite...            return true;        default:            // If we got here, the user's action was not recognized.            // Invoke the superclass to handle it.            return super.onOptionsItemSelected(item);    }}

二.上下文菜单和上下文操作模式
上下文菜单提供了许多操作,这些操作影响 UI 中的特定项目或上下文框架。您可以为任何视图提供上下文菜单,但这些菜单通常用于 ListView、GridView 或用户可直接操作每个项目的其他视图集合中的项目。

提供上下文操作的方法有两种:

  • 使用浮动上下文菜单。用户长按(按住)一个声明支持上下文菜单的视图时,菜单显示为菜单项的浮动列表(类似于对话框)。 用户一次可对一个项目执行上下文操作。

  • 使用上下文操作模式。此模式是 ActionMode 的系统实现,它将在屏幕顶部显示上下文操作栏,其中包括影响所选项的操作项目。当此模式处于活动状态时,用户可以同时对多项执行操作(如果应用允许)。

1.创建上下文菜单
(1)通过调用 registerForContextMenu(),注册应与上下文菜单关联的 View 并将其传递给 View。如果 Activity 使用 ListView 或 GridView 且您希望每个项目均提供相同的上下文菜单,请通过将 ListView 或 GridView 传递给 registerForContextMenu(),为上下文菜单注册所有项目。

(2)在 Activity 或 Fragment 中实现 onCreateContextMenu() 方法。
当注册后的视图收到长按事件时,系统将调用您的 onCreateContextMenu() 方法。在此方法中,您通常可通过扩充菜单资源来定义菜单项。例如:

@Overridepublic void onCreateContextMenu(ContextMenu menu, View v,                                ContextMenuInfo menuInfo) {    super.onCreateContextMenu(menu, v, menuInfo);    MenuInflater inflater = getMenuInflater();    inflater.inflate(R.menu.context_menu, menu);}

MenuInflater 允许您通过菜单资源扩充上下文菜单。回调方法参数包括用户所选的 View,以及一个提供有关所选项的附加信息的 ContextMenu.ContextMenuInfo 对象。如果 Activity 有多个视图,每个视图均提供不同的上下文菜单,则可使用这些参数确定要扩充的上下文菜单。
(3)实现 onContextItemSelected()。用户选择菜单项时,系统将调用此方法,以便您能够执行适当的操作。 例如:

@Overridepublic boolean onContextItemSelected(MenuItem item) {    AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();    switch (item.getItemId()) {        case R.id.edit:            editNote(info.id);            return true;        case R.id.delete:            deleteNote(info.id);            return true;        default:            return super.onContextItemSelected(item);    }}

getItemId() 方法将查询所选菜单项的 ID,您应使用 android:id 属性将此 ID 分配给 XML 中的每个菜单项,如使用 XML 定义菜单部分所示。
成功处理菜单项后,系统将返回 true。如果未处理菜单项,则应将菜单项传递给超类实现。 如果 Activity 包括片段,则 Activity 将先收到此回调。 通过在未处理的情况下调用超类,系统会将事件逐一传递给每个片段中相应的回调方法(按照每个片段的添加顺序),直到返回 true 或 false 为止。(Activity 和 android.app.Fragment 的默认实现返回 false,因此您始终应在未处理的情况下调用超类。)

2.使用上下文操作模式
应用如何调用上下文操作模式以及如何定义每个操作的行为,具体取决于您的设计。

设计基本上分为两种:

  • 针对单个任意视图的上下文操作。
  • 针对 ListView 或 GridView 中项目组的批处理上下文操作(允许用户选择多个项目并针对所有项目执行操作)

(1)为单个视图启用上下文操作模式:

  • 实现 ActionMode.Callback 接口。在其回调方法中,您既可以为上下文操作栏指定操作,又可以响应操作项目的点击事件,还可以处理操作模式的其他生命周期事件。
  • 当需要显示操作栏时(例如,用户长按视图),请调用 startActionMode()。
    例如:
    实现 ActionMode.Callback 接口:
private ActionMode.Callback mActionModeCallback = new ActionMode.Callback() {    // Called when the action mode is created; startActionMode() was called    @Override    public boolean onCreateActionMode(ActionMode mode, Menu menu) {        // Inflate a menu resource providing context menu items        MenuInflater inflater = mode.getMenuInflater();        inflater.inflate(R.menu.context_menu, menu);        return true;    }    // Called each time the action mode is shown. Always called after onCreateActionMode, but    // may be called multiple times if the mode is invalidated.    @Override    public boolean onPrepareActionMode(ActionMode mode, Menu menu) {        return false; // Return false if nothing is done    }    // Called when the user selects a contextual menu item    @Override    public boolean onActionItemClicked(ActionMode mode, MenuItem item) {        switch (item.getItemId()) {            case R.id.menu_share:                shareCurrentItem();                mode.finish(); // Action picked, so close the CAB                return true;            default:                return false;        }    }    // Called when the user exits the action mode    @Override    public void onDestroyActionMode(ActionMode mode) {        mActionMode = null;    }};

调用 startActionMode() 以便适时启用上下文操作模式,例如:响应对 View 的长按操作:

someView.setOnLongClickListener(new View.OnLongClickListener() {    // Called when the user long-clicks on someView    public boolean onLongClick(View view) {        if (mActionMode != null) {            return false;        }        // Start the CAB using the ActionMode.Callback defined above        mActionMode = getActivity().startActionMode(mActionModeCallback);        view.setSelected(true);        return true;    }});

注:在 ListView 或 GridView 中启用批处理上下文操作
如果您在 ListView 或 GridView 中有一组项目(或 AbsListView 的其他扩展),且需要允许用户执行批处理操作,则应:

  • 实现 AbsListView.MultiChoiceModeListener 接口,并使用 setMultiChoiceModeListener() 为视图组设置该接口。在侦听器的回调方法中,您既可以为上下文操作栏指定操作,也可以响应操作项目的点击事件,还可以处理从 ActionMode.Callback 接口继承的其他回调。
  • 使用 CHOICE_MODE_MULTIPLE_MODAL 参数调用 setChoiceMode()。

例如:

ListView listView = getListView();listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);listView.setMultiChoiceModeListener(new MultiChoiceModeListener() {    @Override    public void onItemCheckedStateChanged(ActionMode mode, int position,                                          long id, boolean checked) {        // Here you can do something when items are selected/de-selected,        // such as update the title in the CAB    }    @Override    public boolean onActionItemClicked(ActionMode mode, MenuItem item) {        // Respond to clicks on the actions in the CAB        switch (item.getItemId()) {            case R.id.menu_delete:                deleteSelectedItems();                mode.finish(); // Action picked, so close the CAB                return true;            default:                return false;        }    }    @Override    public boolean onCreateActionMode(ActionMode mode, Menu menu) {        // Inflate the menu for the CAB        MenuInflater inflater = mode.getMenuInflater();        inflater.inflate(R.menu.context, menu);        return true;    }    @Override    public void onDestroyActionMode(ActionMode mode) {        // Here you can make any necessary updates to the activity when        // the CAB is removed. By default, selected items are deselected/unchecked.    }    @Override    public boolean onPrepareActionMode(ActionMode mode, Menu menu) {        // Here you can perform updates to the CAB due to        // an invalidate() request        return false;    }});

三.创建弹出菜单:
1.PopupMenu 是锚定到 View 的模态菜单。如果空间足够,它将显示在定位视图下方,否则显示在其上方。它适用于:

如果使用 XML 定义菜单,则显示弹出菜单的方法如下:

  • 实例化 PopupMenu 及其构造函数,该函数将提取当前应用的 Context 以及菜单应锚定到的 View。
  • 使用 MenuInflater 将菜单资源扩充到 PopupMenu.getMenu() 返回的 Menu 对象中。
  • 调用 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" />
public void showPopup(View v) {    PopupMenu popup = new PopupMenu(this, v);    MenuInflater inflater = popup.getMenuInflater();    inflater.inflate(R.menu.actions, popup.getMenu());    popup.show();}

2.处理点击事件
要在用户选择菜单项时执行操作,您必须实现 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();}@Overridepublic 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 0
原创粉丝点击