菜单总结

三种菜单总结

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

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

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

.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 的应用栏。例如:

@Override
protected 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" >

    
    <item
        android:id="@+id/action_favorite"
        android:icon="@drawable/ic_favorite_black_48dp"
        android:title="@string/action_favorite"
        app:showAsAction="ifRoom"/>

    
    <item android:id="@+id/action_settings"
          android:title="@string/action_settings"
          app:showAsAction="never"/>

menu>

6.添加操作事件

@Override
public 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() 方法。在此方法中,您通常可通过扩充菜单资源来定义菜单项。例如:

@Override
public 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()。用户选择菜单项时,系统将调用此方法,以便您能够执行适当的操作。 例如:

@Override
public 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 属性显示弹出菜单的按钮
"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();
}

@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;
    }
}

你可能感兴趣的:(Android)