菜单的创建并不复杂,关键是要能从整体把握菜单的机制。“坚实的框架”宏观介绍,“详细说明”对一些关键进行说明,“代码示例”帮助理解。
一,坚实的框架
res/menu/**.xml , 资源文件,是创建菜单的一种方式,另一种是直接用代码动态添加。
Activity.onCreateOptionsMenu() ,Activity.onCreateContextMenu(),创建选项菜单和上下文菜单的函数,程序启动时才执行这个函数,所以只能执行一次,如果想更改菜单,要用下一个函数。
Activity.onPrepareOptionsMenu() ,显式菜单前执行这个函数。(貌似木有onPrepareContextMenu()函数 !!)。
Activity.onMenuItemSelected(),网上到处都在说执行下面两个函数前先执行这个函数,我试了下,貌似不是这样的。。。难道我错了?
Activity.onOptionsMenuSelected(),选项菜单的处理。
Activity.onContextMenuSelected(),上下文菜单的处理。
Activity.onOptionsMenuClosed,在选项菜单关闭时被调用。
Activity.onContextMenuClosed,在上下文菜单关闭时调用。
二,详细说明
1,getMenuInflater().inflate(args);从资源文件创建菜单。
2,menu.add(args);动态创建菜单。
3,item一些重要属性:
(1).资源文件实现子菜单
子菜单通过在item元素中嵌套menu来实现。
<item android:title="系统设置">
<menu>
<item android:id="@+id/mi_display_setting"
android:title="显示设置"/>
<item android:id="@+id/mi_network_setting"
android:title="网络设置"/>
<!-- 别的菜单项 -->
</menu>
</item>
(2).为菜单项添加图标
<item android:id="@+id/mi_exit"
android:title="退出"
android:icon="@drawable/exit"/>
(3).设置菜单项的可选出现
使用android:checkableBehavior设置一组菜单项的可选策略,可选值为:none, all, single
<group android:id="..."
android:checkableBehavior="all">
<!-- 菜单项 -->
</group>
使用android:checked设置特定菜单项
<item android:id="..."
android:title="sometitle"
android:checked="true"/>
(4).设置菜单项可用/不可用
<item android:id="..."
android:title="sometitle"
android:enabled="false"/>
(5).设置菜单项可见/不可见
<item android:id="..."
android:title="sometitle"
android:visible="false"/>
三,代码示例
定义菜单的main.xml资源文件
<menu xmlns:android="http://schemas.android.com/apk/res/android" > <group android:id="@+id/group1"> <item android:id="@+id/item11" android:title="item11"></item> <item android:id="@+id/item12" android:title="item12"></item> </group> <group android:id="@+id/group2" android:checkableBehavior="all" > <!-- 改组的所有项都可选 --> <item android:id="@+id/item_21" android:title="item21" android:visible="false"></item> <!-- 该项不可见 --> <item android:id="@+id/item22" android:title="item22" android:enabled="false"></item> <!-- 该项不可用 --> <item android:id="@+id/item23" android:title="item23" android:checked="true"></item> <!-- 该项已被选中 --> </group> </menu>
MainActivity.java文件
package com.example.androidtest; import android.os.Bundle; import android.app.Activity; import android.content.Intent; import android.util.Log; import android.view.ContextMenu; import android.view.ContextMenu.ContextMenuInfo; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.View.OnCreateContextMenuListener; import android.widget.Button; import android.widget.Toast; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button btn = (Button) findViewById(R.id.btn_1); btn.setOnCreateContextMenuListener(new OnCreateContextMenuListener(){ public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { //super.onCreateContextMenu(menu, v, menuInfo); CreateMenu(menu); } }); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); // 从xml资源文件创建 CreateMenu(menu); // 用代码动态创建 return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { Log.w("Trace", "onOptionsItemSelected"); return MenuChoice(item); } private void CreateMenu(Menu menu) { MenuItem item1 = menu.add(0, 0, 0, "menu_item_1"); // 用add添加item,返回item MenuItem item2 = menu.add(0, 1, 1, "menu_item_2"); MenuItem item3 = menu.add(0, 2, 2, "menu_item_3"); MenuItem item4 = menu.add(0, 3, 3, "menu_item_4"); { Intent intent = new Intent(this, MenuActivity.class); item4.setIntent(intent); } // 从网上看到说如果不在onOptionsItemSelected()等里面处理事件,就默认用绑定的事件作响应。但是,这里没看到效果 } private boolean MenuChoice(MenuItem item) { switch( item.getItemId() ) { case 0: Toast.makeText(this, "click on menu_item_1", Toast.LENGTH_SHORT).show(); return true; case 1: Toast.makeText(this, "click on menu_item_2", Toast.LENGTH_SHORT).show(); return true; case 2: Toast.makeText(this, "click on menu_item_3", Toast.LENGTH_SHORT).show(); return true; // 将3的处理使用绑定的活动,但是没效果,不知为什么?? // case 3: // Toast.makeText(this, "click on menu_item_4", Toast.LENGTH_SHORT).show(); // return true; // 对资源文件中的item的处理方法很多,这里使用id,值得注意的是这里的id和用add方法添加的item的id本质相同。 case R.id.item11: Toast.makeText(this, "click on item11 from xml", Toast.LENGTH_SHORT).show(); return true; } return false; } // @Override // public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) // { // super.onCreateContextMenu(menu, v, menuInfo); // CreateMenu(menu); // } @Override public boolean onContextItemSelected(MenuItem item) { Log.w("Trace", "onContextItemSelected"); switch(item.getItemId() ) { case 0: Toast.makeText(this, "menu_item_1 in context menu", Toast.LENGTH_SHORT).show(); return true; case 1: Toast.makeText(this, "menu_item_2 in context menu", Toast.LENGTH_SHORT).show(); return true; case 2: Toast.makeText(this, "menu_item_3 in context menu", Toast.LENGTH_SHORT).show(); return true; case 3: Toast.makeText(this, "menu_item_4 in context menu", Toast.LENGTH_SHORT).show(); return true; } return false; } }