创建一个菜单布局 :
<?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);
}
在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;
}
?
长按按钮弹出菜单
<?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();
}
});
?