Android菜单设计(2) : options menu使用注意事项
16lz
2021-01-25
在Android菜单设计(1) : 使用xml文件布局创建 options menu文章中,初步认识了选项菜单。但是在实际开发中,还是需要注意几个问题,该篇讨论相关问题。
进入正式话题之前,需要了解一些东西。
1. 使用xml方式创建选项菜单
<?xml version="1.0" encoding="utf-8"?><menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/new_game" android:icon="@drawable/ic_new_game" android:title="@string/new_game" /> <item android:id="@+id/help" android:icon="@drawable/ic_help" android:title="@string/help" /></menu>需要注意:在使用menu.getItem(int index)方法时,参数index就是您在xml中创建item的顺序,如上面id为new_game的菜单就是index=0的选项,而id为help的菜单就是index=1的选项。
该方法声明:
MenuItem android.view.Menu.getItem(int index)Gets the menu item at the given index.Parameters: index The index of the menu item to return.Returns: The menu item.Throws: IndexOutOfBoundsException - when index < 0 || >= size()
2. 菜单xml属性
这里只说一个属性,android:enabled=["true" | "false"],对应的方法setEable(boolean)。该属性用来设置菜单是否可用。如下图所示,左边是不可用,右边可用。
其它更加详细的文档,在sdk-path/doc/Dev Guide/Framework Topics/Application Resources/Resource Types/Menu,可以研读一下。
ok,回到主题上来。
3. 工程目录结构
4. Activity代码
package mark.zhang;import android.app.Activity;import android.os.Bundle;import android.util.Log;import android.view.LayoutInflater;import android.view.Menu;import android.view.MenuInflater;import android.view.MenuItem;import android.view.View;import android.view.View.OnClickListener;import android.widget.EditText;public class TestMenuEnableActivity extends Activity {private MenuItem item_ClearAll = null;private EditText showInfo = null; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); showInfo = (EditText) findViewById(R.id.testMenu_edit); item_ClearAll = (MenuItem) findViewById(R.id.menu_clearAll); findViewById(R.id.testMenu_button).setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {if(item_ClearAll != null) {item_ClearAll.setEnabled(true);showInfo.setText("it enables item_ClearAll successfully!");} else {showInfo.setText("item_ClearAll is Null,it do not enable item_ClearAll!");}}}); } @Overridepublic boolean onCreateOptionsMenu(Menu menu) {MenuInflater inflater = getMenuInflater();inflater.inflate(R.menu.ui_optionsmenu, menu);//item_ClearAll = (MenuItem) findViewById(R.id.menu_clearAll);//item_ClearAll = menu.getItem(0);return super.onCreateOptionsMenu(menu);}@Overridepublic boolean onOptionsItemSelected(MenuItem item) {switch(item.getItemId()) {case R.id.menu_clearAll:// 清除所有记录Log.d("mark", "clearAll");return true;case R.id.menu_help:// 帮助Log.d("mark", "help");return true;case R.id.menu_exit:finish();return true;default:return super.onOptionsItemSelected(item);}}}5. menu的xml文件
<?xml version="1.0" encoding="UTF-8"?><menu xmlns:android="http://schemas.android.com/apk/res/android"android:id="@+id/mymenu"><item android:id="@+id/menu_clearAll" android:title="清除所有记录"android:enabled="false" /><item android:id="@+id/menu_help" android:title="帮助" /><item android:id="@+id/menu_exit" android:title="退出" /></menu>注意:在这里将id为menu_clearAll的菜单设置不可用。在Activity代码中(Button点击事件)将其恢复可用。
运行应用程序,界面如下:
点击test menu,显示结果:
可以发现,使用findViewById方法无法获得菜单实例(MenuItem)对象。然后,我将代码:
item_ClearAll = (MenuItem) findViewById(R.id.menu_clearAll);放到回调方法onCreateOptionsMenu中,修改如下:
@Overridepublic boolean onCreateOptionsMenu(Menu menu) {MenuInflater inflater = getMenuInflater();inflater.inflate(R.menu.ui_optionsmenu, menu);item_ClearAll = (MenuItem) findViewById(R.id.menu_clearAll);//item_ClearAll = menu.getItem(0);return super.onCreateOptionsMenu(menu);}再次运行,先点击手机的menu按键,确保回调onCreateOptionsMenu从而执行item_ClearAll = (MenuItem) findViewById(R.id.menu_clearAll);效果如下:
然后点击test menu,还是无法创建(MenuItem)对象。汗!
修改回调方法代码,如下:
@Overridepublic boolean onCreateOptionsMenu(Menu menu) {MenuInflater inflater = getMenuInflater();inflater.inflate(R.menu.ui_optionsmenu, menu);//item_ClearAll = (MenuItem) findViewById(R.id.menu_clearAll);item_ClearAll = menu.getItem(0);return super.onCreateOptionsMenu(menu);}可以看出,使用getItem方法创建MenuItem对象。当然,需要先点击menu按键,然后点击test menu,最后再次点击menu按键,才会有如下效果。
呵呵,创建menuItem对象成功,并且菜单已经使能。
6. 思考
使用LayoutInflater的inflate方法,试一试?
LayoutInflater inflater = LayoutInflater.from(this);View view = inflater.inflate(R.menu.ui_optionsmenu, null);item_ClearAll = (MenuItem)view.findViewById(R.id.menu_clearAll);将上面代码放到回调方法onCreateOptionsMenu或者其它地方,运行之后,报异常:
08-15 06:29:48.195: ERROR/AndroidRuntime(876): Caused by: java.lang.ClassNotFoundException: android.view.menu in loader [email protected]08-15 06:29:48.195: ERROR/AndroidRuntime(876): at dalvik.system.PathClassLoader.findClass(PathClassLoader.java:243)08-15 06:29:48.195: ERROR/AndroidRuntime(876): at java.lang.ClassLoader.loadClass(ClassLoader.java:573)08-15 06:29:48.195: ERROR/AndroidRuntime(876): at java.lang.ClassLoader.loadClass(ClassLoader.java:532)08-15 06:29:48.195: ERROR/AndroidRuntime(876): at android.view.LayoutInflater.createView(LayoutInflater.java:466)08-15 06:29:48.195: ERROR/AndroidRuntime(876): at android.view.LayoutInflater.onCreateView(LayoutInflater.java:544)08-15 06:29:48.195: ERROR/AndroidRuntime(876): at com.android.internal.policy.impl.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:66)08-15 06:29:48.195: ERROR/AndroidRuntime(876): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:563)最后,研究了一下源码:
public View inflate(int resource, ViewGroup root, boolean attachToRoot) { if (DEBUG) System.out.println("INFLATING from resource: " + resource); XmlResourceParser parser = getContext().getResources().getLayout(resource); try { return inflate(parser, root, attachToRoot); } finally { parser.close(); } }可以看出,该方法一般是用来解析layout文件夹下面的资源文件的。而menu是res下面的一个文件夹,不属于layout。如果注意观察的话,在回调方法onCreateOptionsMenu中,使用:
MenuInflater inflater = getMenuInflater();inflater.inflate(R.menu.ui_optionsmenu, menu);来实例化menu这个文件夹。该inflate方法源码:
public void inflate(int menuRes, Menu menu) { XmlResourceParser parser = null; try { parser = mContext.getResources().getLayout(menuRes); AttributeSet attrs = Xml.asAttributeSet(parser); parseMenu(parser, attrs, menu); } catch (XmlPullParserException e) { throw new InflateException("Error inflating menu XML", e); } catch (IOException e) { throw new InflateException("Error inflating menu XML", e); } finally { if (parser != null) parser.close(); } }关于menu,推荐一篇文章: http://www.cnblogs.com/xirihanlin/archive/2010/06/25/1765261.html
更多相关文章
- 没有一行代码,「2020 新冠肺炎记忆」这个项目却登上了 GitHub 中
- Android(安卓)LruCache技术原理
- android:theme 与 setTheme()设置透明效果并不同
- Handler的使用方法――在子线程中更新界面 .
- 通用(任何android机型)Root教程(完整版!附砖机自救方法)转自安卓
- Android(安卓)安全之 Activity 劫持防护
- Android(安卓)---- WebView与JavaScript交互调用(1)
- No cached version of androidx.appcompat:appcompat:1.1.0 avai
- Android(安卓)混淆代码学习以及Android加密工具--APKProtect的使