在上一篇文章 Android 菜单简析01(OptionsMenu) 中给大家介绍了OptionsMenu 的使用,这篇接着给大家介绍下ContextMenu 的用法。
ContextMenu 简称上下文菜单,通过长按事件响应,有两种响应模式
- 浮动模式
效果类似弹出的 Dialog,在屏幕的正中央,可以自定义显示的 Menu 以及 MenuItem 的响应
- 动作模式
通过ActionBar 实现,效果实在 Title 的地方,出现动作条。
特别注意
ContextMenu 的 动作模式 在 Android 3.0 之前的版本无法实现(动作模式需要 ActionBar支持),如果应用 SherlockActionBar 是否支持暂时没有验证。
先看下 动作模式 的效果图
坑爹的 csdn 上传不了图片
第一张图:长按之后的显示效果,App 的 title 变为 ActionMode ,会看到我们的 MenuItem 只有图标,没有文字。
第二张图:点击更多之后,没有显示的 MenuItem ,只有文字,没有图标。
再看下 ContextMenu 的 浮动模式 效果图
坑爹的 csdn 上传不了图片
长按 Btn ,就弹出上图的界面,点击 MenuItem 或者菜单之外的区域,菜单消失。
在低版本上,Android 3.0 之前,ContextMenu 的浮动效果一致,都是如上图所示,使用方法也一样。
现在看下如何创建 ContextMenu ,以及调用的方法。
一、动作模式
ContextMenu 的动作模式创建过程
- 注册动作模式
// 给 Btn 注册动作模式 registerForContextMenu(btnView); // 响应长按事件 btn.setOnLongClickListener(new OnLongClickListener() { @Override public boolean onLongClick(View v) { v.setSelected(true); ContextMenu.this.startActionMode(mActionMode); return true; } });
2. 实现动作模式回调接口
/** * *创建回调接口 * */ private ActionMode.Callback mActionMode = new ActionMode.Callback() { @Override public boolean onPrepareActionMode(ActionMode mode, Menu menu) { // TODO Auto-generated method stub return false; } @Override public void onDestroyActionMode(ActionMode mode) { // TODO Auto-generated method stub if (mode != null) { mode = null; } } @Override public boolean onCreateActionMode(ActionMode mode, Menu menu) { MenuInflater inflater = getMenuInflater(); // 添加菜单文件 inflater.inflate(R.menu.main_icon, menu); return true; } @Override public boolean onActionItemClicked(ActionMode mode, MenuItem item) { switch (item.getItemId()) { case R.id.action_share: Log.d(tag, "action_share"); Toast.makeText(getApplicationContext(), "action_share", Toast.LENGTH_SHORT).show(); mode.finish(); break; case R.id.action_save: Log.d(tag, "action_save"); Toast.makeText(getApplicationContext(), "action_save", Toast.LENGTH_SHORT).show(); mode.finish(); break; case R.id.action_settings: Log.d(tag, "action_settings"); Toast.makeText(getApplicationContext(), "action_settings", Toast.LENGTH_SHORT).show(); mode.finish(); break; case R.id.action_delete: Log.d(tag, "action_delete"); Toast.makeText(getApplicationContext(), "action_delete", Toast.LENGTH_SHORT).show(); mode.finish(); break; case R.id.action_edit: Log.d(tag, "action_edit"); Toast.makeText(getApplicationContext(), "action_edit", Toast.LENGTH_SHORT).show(); mode.finish(); break; default: break; } return true; } };
3 .取消注册动作模式
//取消注册 unRegisterForContextMenu(btnView);
Menu 菜单的 XML 文件
<menu xmlns:android="http://schemas.android.com/apk/res/android" > <item android:id="@+id/action_share" android:orderInCategory="0" android:showAsAction="ifRoom" android:icon="@android:drawable/ic_menu_share" android:title="share"/> <item android:id="@+id/action_save" android:orderInCategory="1" android:showAsAction="ifRoom" android:icon="@android:drawable/ic_menu_save" android:title="save"/> <item android:id="@+id/action_search" android:orderInCategory="2" android:showAsAction="ifRoom" android:icon="@android:drawable/ic_menu_search" android:title="search"/> <item android:id="@+id/action_delete" android:orderInCategory="4" android:showAsAction="ifRoom" android:icon="@android:drawable/ic_menu_delete" android:title="delectAction"/> <item android:id="@+id/action_edit" android:orderInCategory="5" android:showAsAction="ifRoom" android:icon="@android:drawable/ic_menu_edit" android:title="edit"/> <item android:id="@+id/action_help" android:orderInCategory="6" android:showAsAction="ifRoom" android:icon="@android:drawable/ic_menu_help" android:title="help"/> <item android:id="@+id/action_compass" android:orderInCategory="6" android:showAsAction="ifRoom" android:icon="@android:drawable/ic_menu_compass" android:title="compass"/> </menu>
同时 ,动作模式还可以和 ListView 和 GridView 结合
长按 ListView Item 有如下的效果
坑爹的 CSDN 上传不了图
具体代码实现
listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL); listView.setMultiChoiceModeListener(new MultiChoiceModeListener() { @Override public boolean onPrepareActionMode(ActionMode mode, Menu menu) { // TODO Auto-generated method stub return false; } @Override public void onDestroyActionMode(ActionMode mode) { // TODO Auto-generated method stub } @Override public boolean onCreateActionMode(ActionMode mode, Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.main_icon, menu); return true; } @Override public boolean onActionItemClicked(ActionMode mode, MenuItem item) { switch (item.getItemId()) { case R.id.action_share: Log.d(tag, "action_share"); // 修改title mode.setTitle("action_share"); Toast.makeText(getApplicationContext(), "action_share", Toast.LENGTH_SHORT).show(); mode.finish(); break; case R.id.action_save: Log.d(tag, "action_save"); Toast.makeText(getApplicationContext(), "action_save", Toast.LENGTH_SHORT).show(); mode.finish(); break; default: break; } return true; } @Override public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) { // TODO Auto-generated method stub } });
二、浮动模式
- 创建菜单
- 设置菜单监听事件
具体的代码过程
@Override public void onCreateContextMenu(android.view.ContextMenu menu, View v, ContextMenuInfo menuInfo) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.main_icon, menu); super.onCreateContextMenu(menu, v, menuInfo); } @Override public boolean onContextItemSelected(MenuItem item) { // 监听事件只做了部分响应 switch (item.getItemId()) { case R.id.action_compass: break; case R.id.action_delete: break; default: break; } return super.onContextItemSelected(item); }
Menu 的 XML 文件与 动作模式相同
虽然 Menu 菜单有图标,但是 ContextMenu 不支持图标,这个官网有说明。
这样就完成了基本的 ContextMenu 浮动模式的菜单。
与 ContextMenu 相关的其他几个方法
/** * *打开菜单 * * */ @Override public void openContextMenu(View view) { // TODO Auto-generated method stub super.openContextMenu(view); } /** * *关闭菜单 * * */ @Override public void closeContextMenu() { // TODO Auto-generated method stub super.closeContextMenu(); } /** * *关闭菜单之后的监听事件 * * */ @Override public void onContextMenuClosed(Menu menu) { super.onContextMenuClosed(menu); }
这几个方法可以根据自己的需求,选择性实现。
ContextMenu 的相关知识就给大家介绍到这里,有什么问题欢迎大家交流。
下一篇给大家介绍 PopMenu 的相关知识