0
点赞
收藏
分享

微信扫一扫

【达内课程】OptionsMenu


文章目录

  • ​​介绍​​
  • ​​简单使用​​
  • ​​通过xml创建选项菜单​​
  • ​​动态添加菜单​​
  • ​​配置子菜单​​
  • ​​通过xml添加子菜单​​
  • ​​动态添加子菜单​​
  • ​​显示图标​​
  • ​​Fragment中使用OptionsMenu​​
  • ​​实现右上角更多显示菜单​​
  • ​​OptionMenu弹出位置​​

介绍

OptionMenu 选项菜单,是通过点击设备上的 Menu 键弹出的菜单

【配置菜单】
加载 OptionMenu 是通过执行 Activity 中的 ​​​onCreateOptionMenu()​​​方法来实现的。
1、通过配置 res/menu/ 下的菜单配置文件,可以设置菜单项,每个菜单项中:​​​android:id​​​ 属性是其唯一标识,亦用于响应点击菜单项时的匹配;​​android:orderInCategory​​​属性表示菜单项的排序,由小到大排序,如果数字相同,按照代码先后顺序显示;
​​​android:showAsAction​​​属性可以无视;
​​​android:title​​​属性表示菜单项显示的文字;
​​​android:icon​​​属性可以为菜单项配置小图标
2、可以通过在 ​​​onCreateOptionMenu()​​​方法中调用参数 Menu 对象的 ​​add()​​方法动态的添加菜单项

【响应菜单项的点击】
通过重写 ​​​onOptionItemSelected()​​方法可以实现对菜单项的选择的响应

简单使用

通过xml创建选项菜单

MenuActivity

public class MenuActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_menu);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_file:
Toast.makeText(this, "点击了File", Toast.LENGTH_SHORT).show();
break;
case R.id.action_edit:
Toast.makeText(this, "点击了Edit", Toast.LENGTH_SHORT).show();
break;
case R.id.action_view:
Toast.makeText(this, "点击了View", Toast.LENGTH_SHORT).show();
break;
}
return super.onOptionsItemSelected(item);
}
}

在 res 下新建 menu 文件夹,在其中创建 main.xml

<?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/action_file"
android:orderInCategory="100"
android:title="File"
app:showAsAction="never" />
<item
android:id="@+id/action_edit"
android:orderInCategory="100"
android:title="Edit"
app:showAsAction="never" />
<item
android:id="@+id/action_view"
android:orderInCategory="100"
android:title="View"
app:showAsAction="never" />
</menu>

我们运行到模拟机上,虽然模拟机已经没有了 Menu 键,但可以使用 Ctrl+M 快捷键来实现点击了 Menu 键。Menu 之所以显示在下面是因为 MenuActivity 使用的是 NotitleBar 的主题。
【达内课程】OptionsMenu_xml

动态添加菜单

​menu.add(groupid,itemid,order,title);​

​groupid​​​,是分组 id,但是由于安卓中的分组没有明显的效果,这里我们都给 0
​​​itemid​​​是不能冲突的,因为我们一会儿要通过​​item.getItemId()​​​来获得​​itemid​​​来进行响应
​​​order​​​是排序
​​​title​​就是最后显示的文字

栗子:通过代码动态添加菜单

public class MenuActivity extends AppCompatActivity {
public static final int MENU_ITEM_NAVIGATE = 1;
public static final int MENU_ITEM_CODE = 2;
public static final int MENU_ITEM_ANALYZE = 3;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_menu);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
//getMenuInflater().inflate(R.menu.main,menu);
menu.add(Menu.NONE, MENU_ITEM_NAVIGATE, Menu.NONE, "Navigate");
menu.add(Menu.NONE, MENU_ITEM_CODE, Menu.NONE, "Code");
menu.add(Menu.NONE, MENU_ITEM_ANALYZE, Menu.NONE, "Analyze");
return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case MENU_ITEM_NAVIGATE:
Toast.makeText(this, "点击了Navigate", Toast.LENGTH_SHORT).show();
break;
case MENU_ITEM_CODE:
Toast.makeText(this, "点击了Code", Toast.LENGTH_SHORT).show();
break;
case MENU_ITEM_ANALYZE:
Toast.makeText(this, "点击了Analyze", Toast.LENGTH_SHORT).show();
break;
}
return super.onOptionsItemSelected(item);
}
}

效果和刚才是相同的

配置子菜单

1、将一级菜单项的节点修改为首位标签对应的格式,如​​<item></item>​​​,并在该节点下添加​​<menu></menu>​​​子节点,然后在​​<menu></menu>​​​子节点中再添加若干个下级的​​<item>​​​节点来配置各菜单项
2、将添加一级菜单的​​​add()​​​方法修改为 ​​addSubMenu()​​​方法,并获取该方法的返回值,即 SubMenu 类型的对象,然后调用 SubMenu 对象的 ​​add()​​方法添加子菜单

【达内课程】OptionsMenu_android_02

通过xml添加子菜单

修改menu菜单文件

<?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/action_file"
android:orderInCategory="100"
android:title="File"
app:showAsAction="never">
<menu>
<item
android:id="@+id/action_new"
android:orderInCategory="100"
android:title="New"
app:showAsAction="never" />
<item
android:id="@+id/action_open"
android:orderInCategory="100"
android:title="Open"
app:showAsAction="never" />
</menu>
</item>
<item
android:id="@+id/action_edit"
android:orderInCategory="100"
android:title="Edit"
app:showAsAction="never" />
<item
android:id="@+id/action_view"
android:orderInCategory="100"
android:title="View"
app:showAsAction="never" />
</menu>

动态添加子菜单

【达内课程】OptionsMenu_OptionsMenu_03
通过​​​add​​​添加的菜单是一级菜单,不能拥有子菜单;通过​​menu.addSubMenu()​​添加的菜单能拥有子菜单。

public class MenuActivity extends AppCompatActivity {
public static final int MENU_ITEM_NAVIGATE = 1;
public static final int MENU_ITEM_CODE = 2;
public static final int MENU_ITEM_ANALYZE = 3;
public static final int MENU_ITEM_INSPECT_CODE = 4;
public static final int MENU_ITEM_CODE_CLEANUP = 5;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_menu);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
//getMenuInflater().inflate(R.menu.main,menu);
menu.add(Menu.NONE, MENU_ITEM_NAVIGATE, Menu.NONE, "Navigate");
menu.add(Menu.NONE, MENU_ITEM_CODE, Menu.NONE, "Code");
SubMenu subMenu = menu.addSubMenu(Menu.NONE, MENU_ITEM_ANALYZE, Menu.NONE, "Analyze");
subMenu.add(Menu.NONE, MENU_ITEM_INSPECT_CODE, Menu.NONE, "Inspect Code");
subMenu.add(Menu.NONE, MENU_ITEM_CODE_CLEANUP, Menu.NONE, "Code Cleanup");
return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case MENU_ITEM_NAVIGATE:
Toast.makeText(this, "点击了Navigate", Toast.LENGTH_SHORT).show();
break;
case MENU_ITEM_CODE:
Toast.makeText(this, "点击了Code", Toast.LENGTH_SHORT).show();
break;
case MENU_ITEM_INSPECT_CODE:
Toast.makeText(this, "点击了Inspect Code", Toast.LENGTH_SHORT).show();
break;
case MENU_ITEM_CODE_CLEANUP:
Toast.makeText(this, "点击了Code Cleanup", Toast.LENGTH_SHORT).show();
break;
}
return super.onOptionsItemSelected(item);
}
}

显示图标

【达内课程】OptionsMenu_android_04
menu

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/action_file"
android:icon="@drawable/clock"
android:title="定时" />
<item
android:id="@+id/action_view"
android:icon="@drawable/fingerprint"
android:title="指纹" />
</menu>

程序中重写以下方法

@Override
public boolean onPrepareOptionsMenu(Menu menu) {
if (menu != null) {
if (menu.getClass().getSimpleName().equals("MenuBuilder")) {
try {
Method m = menu.getClass().getDeclaredMethod(
"setOptionalIconsVisible", Boolean.TYPE);
m.setAccessible(true);
m.invoke(menu, true);
} catch (NoSuchMethodException e) {
} catch (Exception e) {
}
}
}
return super.onPrepareOptionsMenu(menu);
}

Fragment中使用OptionsMenu

需要在​​onCreate()​​​中增加​​setHasOptionsMenu(true);​​,否则菜单不显示

public static class DetailsFragment extends Fragment {
@Override
public void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
}

重写以下方法

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.menu_message_option,menu);
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()){
case R.id.xx:
//点击菜单的操作
break;
}
return super.onOptionsItemSelected(item);
}

实现右上角更多显示菜单

【达内课程】OptionsMenu_ide_05

<?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/action_file"
android:icon="@mipmap/ic_message_settings"
android:title="更多"
app:showAsAction="always">
<menu>
<item
android:id="@+id/menu_all_read"
android:title="全部已读" />

<item
android:id="@+id/menu_all_clear"
android:title="清空消息" />
</menu>
</item>
</menu>

OptionMenu弹出位置

OptionMenu 的显示以前是显示在 overflow 的下面,5.0 以后显示的位置直接覆盖了 overflow 图标,我们看到上一个栗子中的菜单就是覆盖效果,那么怎么才能实现以下效果呢?
【达内课程】OptionsMenu_xml_06
解决办法:

  1. 在​​values-v21 styles.xml​​文件中添加
<style name="OverflowMenuStyle" parent="Widget.AppCompat.PopupMenu.Overflow">
<!-- Api 21 -->
<item name="overlapAnchor">false</item>
<!-- 弹出层背景颜色 -->
<item name="android:popupBackground">@color/action_bar_title_text_color</item>
<!-- 设置弹出菜单文字颜色 -->
<item name="android:textColor">@color/message_text</item>
</style>
  1. 在使用的主题中添加
<item name="actionOverflowMenuStyle">@style/OverflowMenuStyle</item>

参考
​​​ActionBar中OptionMenu弹出菜单的位置和overflow右边距的调整​​

举报

相关推荐

0 条评论