目录
菜单资源文件通常放置在res\menu目录下,在创建项目时,默认不自动创建menu目录,所以需手动创建。
Android Resource Directory→ value menu
或在创建根元素为标记的xml文件对自动气建眼
res→Android Resounce File →Resource type→menu
子元素为
标记常用属性,描述:
android: checkableBehavior 用于定义菜单项的选中行为。值可为none(默认值,表示菜单项没有选中状态,无法选择),single(表示只能选择一个菜单项,选择一个菜单项会自动取消其他菜单项的选择状态),all(表示所有菜单项都可以选择,没有互斥的关系)。
andraid: id 设置ID,也就是唯一标识。
android: title 设置标题。
android: alphabeticShortcut 指定字符快捷键。
android: numericShortcut 指定数字快捷键。
android: enabled 是否可用。
android: checkable 是否可选。
android: visible 是否可见。
android: checked 是否已选用。
android: icon 指定图标,需重写onMenuOpened方法并在其中调用设置显示图标才会在列表项中显示图标(重写方法)。
app: actionLayout 用于设置自定义的菜单项布局。在设置本属性时请不要设置title,可能会导致冲突,可用tools:ignore="MenuTitle"替代title。
app: actionViewClass 用于指定操作按钮的视图类的 XML 属性。值可为"androidx.appcompat.widget.SearchView"(搜索框)等。
app: showAsAction 该属性用于溢出菜单,控制菜单项在导航栏上展示位置。值可为:
always 总是在导航栏上显示菜单图标。
ifRoom 如果导航栏右侧有空间,该项就直接显示在导航栏上,不再放入溢出菜单。
never 从不在导航栏上显示,一直放在溢出菜单列表中。
withText 如果能在导航栏上显示,除了显示图标还要显示该项的文字说明。
collapseActionView 操作视图要折叠为一个按钮,点击该按钮再展示操作视图主要用于Searchview。
android: id 为菜单组设置ID。
android: checkableBehavior 指定菜单组选择行为,值可为none(不可选)、all(多选)、single(单选)。
android: menuCategory 对某单组进行分类,指定优先级,值可为container、system、secondary和alternative
android: enable 指定该菜单组中全部 单项是否可用
android: visible 指定该菜单组中全部某单项是否可见
- //例
- "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:title="item1"
- android:icon="@drawable/zerotwo"
- app:showAsAction="always"/>
- <item android:title="item2">
- <menu>
- <item android:title="item2_1"/>
- <item android:title="item2_2"/>
- menu>
- item>
- <group>
- <item android:title="item3"/>
- <item android:title="item4"/>
- group>
-
- menu>
长按注册的控件显示菜单。
无法对其列表中菜单项进行自定义布局,使用app:actionLayout属性无效。
- public class MainActivity extends AppCompatActivity {
-
- protected void onCreate(Bundle savedInstanceState) {
- ... ...
- TextView textView=findViewById(R.id.textView);
- registerForContextMenu(textView);
- }
-
- public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
- //用于创建菜单(上下文菜单)
- getMenuInflater().inflate(R.menu.test,menu);
- }
-
- public boolean onContextItemSelected(MenuItem item) {
- //用于选择菜单项(上下文菜单)
- int id=item.getItemId();
- if(id==R.id.~){
- ~
- }
- return true;
- }
-
- }
溢出菜单和选项菜单仅作为操作栏的扩展,无法对其列表中菜单项进行自定义布局,使用app:actionLayout属性无效。
点击标题栏或工具栏最右侧三个点显示菜单
如果隐藏标题栏ActionBar且没有使用工具栏ToolBar(app:menu)将无法使用。
使用ToolBar时要使用 setSupportActionBar( toolBar ) 将工具栏设为操作栏,且为ToolBar的app:menu属性赋值。
- public class MainActivity extends AppCompatActivity {
-
- public boolean onCreateOptionsMenu(Menu menu) {
- //用于创建菜单(选项菜单/溢出菜单)
- MenuInflater menuInflater=getMenuInflater().inflate(R.menu.test,menu);
- return true;
- }
-
- public boolean onOptionsItemSelected(MenuItem item) {
- //用于选择菜单项(选项菜单/溢出菜单)
- int id=item.getGroupId();
- if(id==R.id.~){
- ~
- }
- return true;
- }
-
- }
溢出菜单和选项菜单仅作为操作栏的扩展,无法对其列表中菜单项进行自定义布局,使用app:actionLayout属性无效。
溢出菜单和选项菜单并无较大差别,均是点击标题栏ActionBar或工具栏ToolBar最右侧三个点显示菜单。
如果隐藏标题栏ActionBar且没有使用工具栏ToolBar(app:menu)将无法使用。
使用ToolBar时要使用 setSupportActionBar( toolBar ) 将工具栏设为操作栏,且为ToolBar的app:menu属性赋值。
菜单栏默认不在某单列表中显示图标;可制作自定义方法来使其显示图标。
- //用于使菜单项在列表中显示图片的自定义方法
- class MyMenuUtil{
- public static void setOverflowIconVisible(int featureId,Menu menu){
- //ActionBar的featureId是8,ToolBar的featureId是108
- if(featureId%100== Window.FEATURE_ACTION_BAR&&menu!=null){
- if(menu.getClass().getSimpleName().equals("MenuBuilder")){
- try {
- //setOptionalIconsVisible是隐藏方法,需要反射机制调用。
- Method m=menu.getClass().getDeclaredMethod("setOptionalIconsVisible",Boolean.TYPE);
- m.setAccessible(true);
- m.invoke(menu,true);
- }
- catch (Exception e){
- e.printStackTrace();
- }
- }
- }
- }
- }
- public class MainActivity extends AppCompatActivity {
-
- public boolean onMenuOpened(int featureId, Menu menu) {
- //打开菜单时调用
- //设置在菜单栏中显示图标
- MyMenuUtil.setOverflowIconVisible(featureId,menu);
- return super.onMenuOpened(featureId, menu);
- }
-
- public boolean onCreateOptionsMenu(Menu menu) {
- //用于创建菜单(溢出菜单/选项菜单)
- MenuInflater menuInflater=getMenuInflater().inflate(R.menu.test,menu);
- return true;
- }
-
- public boolean onOptionsItemSelected(MenuItem item) {
- //用于选择菜单项(溢出菜单/选项菜单)
- int itemId=item.getItemId();
- int groupId=item.getGroupId();
- if(itemId==R.id.~){
- ~
- }
- return true;
- }
- }
点击控件触发;效果与上下文菜单类似。
无法对其列表中菜单项进行自定义布局,使用app:actionLayout属性无效。
- //触发的控件
- Button button=findViewById(R.id.button);
- //监听器
- button.setOnClickListener(new View.OnClickListener() {
- public void onClick(View view) {
-
- //创建PopupMenu对象,参数为环境、触发控件
- PopupMenu popupMenu=new PopupMenu(MainActivity.this,view);
- //填充菜单
- popupMenu.getMenuInflater().inflate(R.menu.navigation_view_menu,popupMenu.getMenu());
- //为弹出菜单设置菜单项监听器
- popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
- public boolean onMenuItemClick(MenuItem menuItem) {
- //点击菜单项执行
- int menuItemId=menuItem.getItemId();
- return true;
- }
- });
- //展示菜单
- popupMenu.show();
-
- }
- });
部分控件所含菜单的菜单项允许自定义布局,在菜单项中添加app:actionLayout属性即可自定义菜单项布局。在设置本属性时请不要设置title,可能会导致冲突,可用tools:ignore="MenuTitle"替代title。
请注意是app:actionLayout不是android:actionLayout。
- "1.0" encoding="utf-8"?>
- xmlns:tools="http://schemas.android.com/tools"
- xmlns:app="http://schemas.android.com/apk/res-auto">
-
-
- android:id="itemId"
- app:actionLayout="@layout/menu_item_layout"
- tools:ignore="MenuTitle" />
-
设置自定义菜单项中的子控件;使用自定义菜单项时可使用menu.findItem()获取指定菜单项,然后使用getActionView()获取菜单项的View,最后使用view.findViewById()获取指定控件。
- //如为自定义菜单项,可进行子控件设置
- //例:
- Menu menu=view.getMenu();
- View menuItemView=menu.findItem(R.id.item1).getActionView();
- ImageView imageView=menuItemView.findViewById(R.id.~);
- imageView.setImageResource(R.drawable.~);
允许使用自定义菜单项菜单的控件有NavigationView(导航控件)。