选项菜单 OptionsMenu
用xml添加(更建议使用)
创建一个菜单布局 :
- 在 res文件下新建一个menu 目录,此时的菜单id为:R.menu.option
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> <!-- 菜单可以嵌套 但顶多允许含有一层子菜单--> <!-- showAsAction:always 直接在标题栏显示 never 不显示 有图标就显示图标 --> <item android:id="@+id/m1" android:title="选项1" app:showAsAction="always"/> <item android:id="@+id/m2" android:title="选项2"/> <item android:id="@+id/m3" android:title="选项3"/> <item android:id="@+id/m4" android:title="选项4"> <menu> <item android:title="子菜单1"/> <item android:title="子菜单2"/> <item android:title="子菜单3"/> <item android:title="子菜单4"/> </menu> </item> </menu>
在需要添加选项菜单的布局对应的activity中创建选项菜单-此时是MainActivity
getMenuInflater().inflate(R.menu.option,menu); // 加载菜单资源
// 创建optionMenu @Override public boolean onCreateOptionsMenu(Menu menu) { // 加载菜单资源 getMenuInflater().inflate(R.menu.option,menu); return true; } // optionMenu 的选中方法 @Override public boolean onOptionsItemSelected(@NonNull MenuItem item) { if (item.getItemId() == R.id.m1) { Toast.makeText(this,item.getTitle(),Toast.LENGTH_SHORT).show(); } else if (item.getItemId() == R.id.m2) { Toast.makeText(this,item.getTitle(),Toast.LENGTH_SHORT).show(); } return super.onOptionsItemSelected(item); }
使用Java添加
- Menu 类 SubMenu 子菜单类
- Menu类参数:组id 菜单项id 菜单项序号 菜单项名称
在onCreateOptionsMenu 方法里利用以上类添加选项菜单,菜单项序号是指菜单项的位置
// 创建optionMenu @Override public boolean onCreateOptionsMenu(Menu menu) { // 加载菜单资源 /* 通过xml设计 */ // getMenuInflater().inflate(R.menu.option,menu); /* 纯代码设计 * Menu 类 SubMenu 子菜单类*/ /* Menu 类参数:组id 菜单项 id 菜单项序号 菜单项名称 */ menu.add(1,1,3,"菜单1"); menu.add(1,2,2,"菜单2"); SubMenu subMenu = menu.addSubMenu(1,3,1,"子菜单的主菜单"); subMenu.add(2,22,1,"子菜单2"); subMenu.add(2,11,2,"子菜单1"); return true; }
上下文菜单 ContextMenu
长按按钮弹出菜单
创建菜单布局
- 在 res文件下新建一个menu 目录,此时的菜单id为:R.menu.context
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/ctx1" android:title="上下文菜单item1" /> <item android:id="@+id/ctx2" android:title="上下文菜单item2" /> <item android:id="@+id/ctx3" android:title="上下文菜单item3" /> <item android:id="@+id/ctx4" android:title="上下文菜单item4" /> <item android:title="上下文菜单item5"> <menu> <item android:id="@+id/z_ctx1" android:title="子菜单item1" /> <item android:id="@+id/z_ctx2" android:title="子菜单item2" /> <item android:id="@+id/z_ctx3" android:title="子菜单item3" /> </menu> </item> </menu>
创建菜单
在activity_main.xml里添加一个按钮用以打开上下文菜单
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:gravity="center" android:layout_width="match_parent" android:layout_height="match_parent"> <Button android:id="@+id/ctx_btn" android:layout_width="200dp" android:layout_height="wrap_content" android:layout_marginTop="20dp" android:text="打开contextMenu"/> </LinearLayout>
上下文菜单的使用步骤:
1.注册
在 activity_main.xml 布局对应的 activity 中的 onCreate() 方法中进行注册
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // ContextMenu 上下文菜单的使用 // 1.注册 registerForContextMenu(findViewById(R.id.ctx_btn)); }
2.创建 - 覆盖父类的 onCreateContextMenu 方法
// 2.创建contextMenu @Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { getMenuInflater().inflate(R.menu.context,menu); }
3菜单项的操作 - 覆盖父类的 onContextItemSelected 方法
// 3.contextMenu 菜单项选项操作 @Override public boolean onContextItemSelected(@NonNull MenuItem item) { int itemId = item.getItemId(); Toast.makeText(this, item.getTitle(), Toast.LENGTH_SHORT).show(); return super.onContextItemSelected(item); }
上下文菜单 - 上下文操作模式
菜单会出现在状态栏的位置
1. 实现接口 ActonMode.CallBack 中不同的回调方法
ActionMode.Callback ac =new ActionMode.Callback(){ // 创建:在启动上下文操作模式(startActionMode(Callback))时调用 @Override public boolean onCreateActionMode(ActionMode mode, Menu menu) { Log.e("上下文操作模式","--创建--"); getMenuInflater().inflate(R.menu.context,menu); return true; } // 准备:在创建方法后进行调用 @Override public boolean onPrepareActionMode(ActionMode mode, Menu menu) { Log.e("上下文操作模式","--准备--"); return false; } // 菜单项被点击 @Override public boolean onActionItemClicked(ActionMode mode, MenuItem item) { /* 环境变量此时需要这样是因为这是一个内部类 ButtonActivity.this */ Log.e("上下文操作模式","--点击--"); Toast.makeText(ButtonActivity.this, item.getTitle(), Toast.LENGTH_SHORT).show(); return true; } // 结束:上下文操作模式结束时调用 @Override public void onDestroyActionMode(ActionMode mode) { Log.e("上下文操作模式","--结束--"); } };
2. 添加一个按钮用以打开,上下文操作模式
<Button android:id="@+id/ctx_opbtn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="20dp" android:text="上下文 ContextMenu 操作模式"/>
3.在View的长按事件中启动上下文操作模式
findViewById(R.id.ctx_opbtn).setOnLongClickListener(new View.OnLongClickListener() { @Override public boolean onLongClick(View v) { startActionMode(ac); return false; } });
弹出式菜单
一般出现在被绑定的View下方,如果下方没有空间则出现在上方
添加一个按钮
<Button android:id="@+id/pop_btn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="20dp" android:text="弹出式菜单"/>
为这个按钮添加点击事件,并将弹出式菜单绑定在按钮的点击事件上
// 将弹出式菜单绑定在按钮的点击事件上 Button popbtn = findViewById(R.id.pop_btn); popbtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // 1.实例化 PopupMenu 对象 /* 参数一 上下文环境 * 参数二 被锚定的(绑定)的button*/ PopupMenu popupMenu = new PopupMenu(ButtonActivity.this,popbtn); // 2.加载菜单资源:利用MenuInflater将Menu资源加载到PopMenu.getMenu() 所返回的Menu对象中 popupMenu.getMenuInflater().inflate(R.menu.context,popupMenu.getMenu()); // 3.菜单子项点击操作 popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem item) { Toast.makeText(ButtonActivity.this, item.getTitle(), Toast.LENGTH_SHORT).show(); return false; } }); // 显示菜单 popupMenu.show(); } });