Android中menu可分为两种,分别为options menu(menu键产生), context menu(长按屏幕产生)
下面举个例子;
1,options menu(menu键产生),
@Override public boolean onCreateOptionsMenu(Menu menu) { m=menu; menu.add(0, Menu.FIRST, 0, "1st"); menu.add(0, Menu.FIRST+1, 0, "2st"); menu.add(0, Menu.FIRST+2, 0, "3st"); menu.add(0, Menu.FIRST+3, 0, "4st"); return super.onCreateOptionsMenu(menu); } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case 1: Toast.makeText(this, "you select"+item.getItemId(), 500).show(); break; case 2: Toast.makeText(this, "you select"+item.getItemId(), 500).show(); break; case 3: Toast.makeText(this, "you select"+item.getItemId(), 500).show(); break; case 4: Toast.makeText(this, "you select"+item.getItemId(), 500).show(); break; } return super.onOptionsItemSelected(item); }
Menu m=null; int count=0; @Override public boolean onPrepareOptionsMenu(Menu menu) { if(count>0){ if(count%2==0){ menu.removeGroup(1); }else{ menu.add(1, Menu.FIRST, 0, "5st"); menu.add(1, Menu.FIRST+1, 0, "6st"); } } count++; return super.onPrepareOptionsMenu(menu); }
2,context menu(长按屏幕产生)
@Override public boolean onContextItemSelected(MenuItem item) { switch (item.getItemId()) { case 1: Toast.makeText(this, "you select"+item.getItemId(), 500).show(); break; case 2: Toast.makeText(this, "you select"+item.getItemId(), 500).show(); break; } return super.onContextItemSelected(item); } @Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { menu.add(0, Menu.FIRST, 0, "1st"); menu.add(0, Menu.FIRST+1, 0, "2st"); super.onCreateContextMenu(menu, v, menuInfo); }还有一步,与View进行绑定;
/** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // setContentView(R.layout.main); MyView my=new MyView(this); setContentView(my); registerForContextMenu(my); }
以上是通过代码实现,还可以通过xml文件实现
menu.xml 内容如下;
<menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/fourth_item" android:orderInCategory="3" android:title="Fourth" /> <item android:id="@+id/third_item" android:orderInCategory="2" android:title="Third" /> <item android:id="@+id/dive" android:orderInCategory="1" android:title="Second" /> <item android:id="@+id/jump" android:orderInCategory="0" android:title="First" /> </menu>
加载xml文件;
@Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the currently selected menu XML resource. MenuInflater inflater = getMenuInflater(); inflater.inflate(sMenuExampleResources[R.m], menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.jump: Toast.makeText(this, "Jump up in the air!", Toast.LENGTH_SHORT).show(); return true; case R.id.dive: Toast.makeText(this, "Dive into the water!", Toast.LENGTH_SHORT).show(); return false; }
在android开发中更多时候需要自定义menu以便实现更好的效果。
基本思路,1,定义menu布局文件,2,重写onkey方法监听menu与back按键,控制菜单显示,3,通过PopupWindow类辅助显示view
menu布局choosemenu.xml
<?xml version="1.0"encoding="utf-8"?> <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal"android:layout_width="fill_parent" android:layout_height="wrap_content"android:gravity="bottom"> <!-- 第一个菜单项:“首页” --> <LinearLayout android:id="@+id/home"android:orientation="vertical" android:layout_width="fill_parent"android:layout_height="wrap_content" android:background="@drawable/button_normal_translucent" android:layout_weight="1"> <ImageView android:layout_width="fill_parent" android:layout_height="wrap_content"android:src="@drawable/home" android:paddingTop="5dp" /> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content"android:text="首页" android:gravity="center" /> </LinearLayout> <!-- 第二个菜单项:“我的” --> <LinearLayout android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content" android:background="@drawable/button_normal"android:layout_weight="1" android:gravity="center"> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/mine"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="我的" /> </LinearLayout> <!-- 第三个菜单项 <LinearLayout android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="wrap_content" android:background="@drawable/button_normal" android:layout_weight="1"> <ImageView android:layout_width="fill_parent" android:layout_height="wrap_content"android:src="@drawable/more" android:paddingTop="18dp" /> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="更多" android:gravity="center"android:paddingTop="5dp"/> </LinearLayout> </LinearLayout>
监听按键并控制显示:
private PopupWindow pop; private View layout; private int state = 2; //状态变量,1:选项菜单已弹出,2:选项菜单未弹出 @Override public boolean onKeyDown(int keyCode, KeyEvent event) { switch (keyCode) { case KeyEvent.KEYCODE_MENU: // 按下“menu”键的动作 // 选项菜单已弹出,不再弹出新的窗口 if (state == 1) return false; // 装载选项菜单布局文件 layout =getLayoutInflater().inflate(R.layout.menu_layout, null); // 创建PopupWindow对象,并在指定位置弹出用于显示菜单的窗口 pop = new PopupWindow(layout,getWindowManager() .getDefaultDisplay().getWidth(), getWindowManager() .getDefaultDisplay().getHeight()); // 设置弹出窗口的位置 pop.showAtLocation(layout,Gravity.BOTTOM, 0, 0); View home = layout.findViewById(R.id.home); // 为“首页”菜单项添加单击事件 home.setOnClickListener(new OnClickListener(){ @Override public void onClick(View view){ Toast.makeText(Main.this, "单击定制菜单.", Toast.LENGTH_LONG).show(); // 单击“首页”菜单项后,关闭选项菜单 pop.dismiss(); // 重新设置状态变量 state = 2; } }); // 弹出选项菜单后,将状态变量设为1,表示选项菜单已弹出 state = 1; return false; case KeyEvent.KEYCODE_BACK: // 按下“back”键的动作 if (state == 1) { // 如果选项菜单已弹出,关闭它 pop.dismiss(); // 将状态变量设为选项菜单已关闭 state = 2; } else if (state == 2){ // 如果选项菜单还没有显示,或已经关闭,则直接关闭当前的Activity finish(); } return false; } // 除“menu”和“back”按下事件外,仍需调用Activity类的onKeyDown方法来响应其他键的按下事件 return super.onKeyDown(keyCode, event); }
在编写上面代码时应注意如下几点:
对于选项菜单来说,一般单击某个菜单项后,会执行一些动作,并且选项菜单会自动关闭。为了模拟这一过程。为“首页”菜单项添加了一个单击事件。
当单击“首页”菜单项时,会弹出一个Toast提示信息,并且选项菜单会关闭。 当执行完按下“menu”或“back”键的动作后,onKeyDown方法应返回一个常量(false或true都可以),
不能再调用super.onKeyDown方法,否则在执行完定制的菜单项动作后,又会执行系统的默认动作。
例如,当按下“back”键后,关闭弹出菜单后,连当前的Activity也一起关了。当然,如果是除了“menu”和“back”的其他键按下时还是需要调用Activity类的onKeyDown方法的
(也就是super.onKeyDown方法),这样在程序中还可以响应其他的按键事件,否则程序除了“menu”和“back”键外,其他的键几乎都不好使了。
showAtLocation方法用于控件弹出窗口的位置。该方法的第1个参数是一个View对象。实际上,showAtLocation方法内部只是需要调用View.getWindowToken方法
来获得一个IBinder对象。showAtLocation方法的第2个参数表示弹出窗口的位置。本例中设置了弹出窗口在屏幕底部显示。最后两个参数分别表示水平和垂直偏移量。
本例都设为0,表示不发生偏移。因此,弹出窗口会在屏幕的最底部显示,也就是显示选项菜单的位置。