android 中的菜单总结
Android中的菜单主要有选项菜单(一般显示在顶部,通过小三角点击显示),上下文菜单(比如选中一个输入框中一段文字,会出现复制粘贴等选项),弹出式菜单(可以显示在任意控件下,样式和第一个差不多,也可以自定义),下面是一个简单的使用小结,更多更好看的样式和功能自己用到时再进一步学习,还有一些其他的如spinner之类的我们就不说了。
1、option menu
选项菜单应该是我们最长用到的菜单了,它的使用也是最简单的。创建步骤如下
-
1、在res/menu目录下创建菜单资源文件,这里名为option_menu.xml,还可以为每个item指定图标icon,简单起见,我这里没有添加。
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/openfile" android:title="打开文件"/> <item android:id="@+id/exit" android:title="退出"/> </menu>
-
重写onCreateOptionsMenu,加载菜单
@Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.option_munu,menu); return true; }
-
重写onOptionsItemSelected,处理菜单选项点击处理逻辑
@Override public boolean onOptionsItemSelected(@NonNull MenuItem item) { switch (item.getItemId()){ case R.id.openfile: Log.d(TAG, "open file"); break; case R.id.exit: Log.d(TAG, "exit program"); break; } return true; }
现在菜单就显示在ActionBar上面了
点击小三角就能显示了,我们编写菜单资源文件时,默认它们都是隐藏的,也可以通过showAsAction指定它们的显示方式,从而显示在小三角之外了,比如
<?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">
<item android:id="@+id/openfile"
android:title="打开文件"
app:showAsAction="always"/>
<item android:id="@+id/newfile"
android:title="创建"
app:showAsAction="never"/>
<item android:id="@+id/exit"
android:title="退出"
app:showAsAction="ifRoom"/>
</menu>
showAsAction有几个值可选,比较常用的有always表示总是显示,ifRoom表示空间足够时显示,never表示永远不显示
2、Context Munu
android 中的上下文菜单,长按某个View之后就会显示出来,比如我们经常长按一段文字,会出现复制,剪切等等菜单选项。和options menu类似,它有一个创建上下文菜单的函数onCreateContextMenu,在其中添加上子菜单项,onContextItemSelected根据选中的不同子菜单做出响应。最后在我们想要设置的View上注册上下文菜单。
看一个简单的例子
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
// 设置标题和标题的图标,也可以自己定制化标题
menu.setHeaderTitle("文本操作");
menu.setHeaderIcon(R.drawable.ic_baseline_attach_file_24);
// 添加子菜单,第一个参数是group,第二个参数是id
menu.add(0,1, Menu.NONE,"复制");
menu.add(0,2,Menu.NONE,"粘贴");
}
@Override
public boolean onContextItemSelected(@NonNull MenuItem item) {
AdapterView.AdapterContextMenuInfo menuInfo = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
// 根据子菜单的id来为做出不同的动作
switch (item.getItemId()){
case 1:
buffer = (String) mainBinding.editText.getText().subSequence(mainBinding.editText.getSelectionStart(),mainBinding.editText.getSelectionEnd());
break;
case 2:
if (buffer!=null){
mainBinding.editText.setText(buffer);
}
break;
}
return true;
}
最后,在想要添加上下文菜单的View上注册
this.registerForContextMenu(editText);
3、popup menu
弹出式菜单,它和options menu非常相似,不同的是,options menu只能在顶部点击进行显示,但是弹出式菜单可以在任意的view下面显示,它的菜单资源可以来自于xml文件,使用非常方便。使用步骤如下
-
1、在res/menu目录下创建一个菜单资源popup_menu.xml
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/copy" android:title="复制"/> <item android:id="@+id/paste" android:title="粘贴"/> </menu>
-
2、创建一个PopupMenu对象,利用该对象加载菜单资源,并设置点击菜单的回调函数。
// 创建popupmenu对象,第一个参数是context,第二个参数是view对象,这里我是指定显示在id为btnTest的按钮下面 PopupMenu popupMenu = new PopupMenu(MainActivity.this,mainBinding.btnTest); // 加载菜单资源 popupMenu.getMenuInflater().inflate(R.menu.popup_menu,popupMenu.getMenu()); // 设置监听器 popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem item) { switch (item.getItemId()){ case R.id.copy: Log.d(TAG, "copy"); break; case R.id.paste: Log.d(TAG, "paste"); break; } return true; } });
其实这里也可以自定义一个菜单样式的布局,然后再加载它
View contentView = LayoutInflater.from(PhotoShow.this).inflate(R.layout.menu_layout,null,false);
window = new PopupWindow(contentView,400, ViewGroup.LayoutParams.WRAP_CONTENT);
window.setContentView(contentView);
-
3、最后,要将菜单显示出来
popupMenu.show()
为了点击菜单之外的地方它能够自动消失,还需要添加上
window.setOutsideTouchable(true);
如果在Activity销毁时,菜单没有被销毁,就会出现窗口泄露之类的错误,因此,在Activity销毁时还需要销毁一下它
if (window != null){
window.dismiss();
window = null;
}
在这里插入代码片
总结一下
他们之间的使用方式是比较相似的
option menu | context menu | popup menu | |
---|---|---|---|
加载方式 | 在函数onCreateOptionsMenu中加载布局文件 | 在函数onCreateContextMenu中添加菜单选项 | 通过PopupMenu对象去加载布局文件 |
处理方式 | 在函数onOptionsItemSelected中处理每个菜单点击逻辑 | 在函数 onContextItemSelected处理 | 在popupMenu对象中添加监听器,在监听器中处理 |
是否需要布局文件 | 需要,定义在res/menu/文件夹下 | 不需要 | 需要,定义在res/menu/文件夹下 |