Menu与ActionBar的爱恨情仇
最近在开发一款音乐播放器,在开发过程中遇到了一点小麻烦,通过android API搞清楚了Menu与ActionBar的爱恨情仇,写了个小Demo祭奠一下那些年我们陷进去的坑,有不对的地方请大神们批评指正。
一.Android系统里的菜单接口(即Menu接口),它是一个父接口,其下又有两个子接口:SubMenu(子菜单)与ContextMenu(上下文菜单)
常用的菜单有以下三类:Option Menu(选项菜单,常与ActionBar连用),Context Menue(上下文菜单),Popup Menu(弹出框菜单),下面就以小Demo的形式介绍它们的使用方法。
1.Option Menu(选项菜单,常与ActionBar连用)
(1)使用Menu的add()方法,代码生成菜单项
/** * 选项菜单 */ public class OptionMenuActivity extends ActionBarActivity { @Override public void onCreate(Bundle savedInstanceState, PersistableBundle persistentState) { super.onCreate(savedInstanceState, persistentState); setContentView(R.layout.activity_menu); } @Override public boolean onCreateOptionsMenu(Menu menu) { //添加菜单项(组ID,当前选项ID,排序,标题) menu.add(0,100,1,"设置游戏"); menu.add(0,200,2,"开始游戏"); menu.add(0,300,3,"退出游戏"); return super.onCreateOptionsMenu(menu); } //菜单选项的单击事件处理方法 @Override public boolean onOptionsItemSelected(MenuItem item) { int id = item.getItemId(); switch (id){ case 100: Toast.makeText(this,"正在打开设置游戏界面. ..",Toast.LENGTH_LONG).show(); break; case 200: Toast.makeText(this,"正在打开开始游戏界面...",Toast.LENGTH_LONG).show(); break; case 300: Toast.makeText(this,"正在打开退出游戏界面...",Toast.LENGTH_LONG).show(); break; default: break; } return super.onOptionsItemSelected(item); } }
效果图如下:
(2)xml文件设置
public class OptionMenuActivity extends AppCompatActivity { @Override public void onCreate(Bundle savedInstanceState, PersistableBundle persistentState) { super.onCreate(savedInstanceState, persistentState); setContentView(R.layout.activity_menu); } @Override public boolean onCreateOptionsMenu(Menu menu) { //引进菜单布局 getMenuInflater().inflate(R.menu.memu_option,menu); return super.onCreateOptionsMenu(menu); } //菜单选项的单击事件处理方法 @Override public boolean onOptionsItemSelected(MenuItem item) { int id = item.getItemId(); switch (id){ case R.id.game_set: Toast.makeText(this,"正在打开设置游戏界面. ..",Toast.LENGTH_LONG).show(); break; case R.id.game_start: Toast.makeText(this,"正在打开开始游戏界面...",Toast.LENGTH_LONG).show(); break; case R.id.game_exit: Toast.makeText(this,"正在打开退出游戏界面...",Toast.LENGTH_LONG).show(); break; default: break; } return super.onOptionsItemSelected(item); } }
<menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" tools:context=".OptionMenuActivity"> <item android:id="@+id/game_set" android:title="设置游戏" android:orderInCategory="0" app:showAsAction="never" /> <item android:id="@+id/game_start" android:title="开始游戏" android:orderInCategory="1" app:showAsAction="never" /> <item android:id="@+id/game_exit" android:title="退出游戏" android:orderInCategory="2" app:showAsAction="never" /> </menu>
效果图如下:
注意事项:showAsAction与orderInCategory的作用
showAsAction主要是针对菜单的显示起作用的,它有三个可选项
always:总是显示在界面上
never:不显示在界面上,只让出现在右边的三个点中
ifRoom:如果有位置才显示,不然就出现在右边的三个点中
orderInCategory="100"(优先级,值越大优先级越低)
showAsAction="always"时的效果:(都未被放到了菜单项中,而是显示到ActionBar上了)
<menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" tools:context=".OptionMenuActivity"> <item android:id="@+id/game_start" android:title="开始游戏" android:orderInCategory="1" app:showAsAction="always" /> <item android:id="@+id/game_set" android:title="设置游戏" android:orderInCategory="0" app:showAsAction="always" /> <item android:id="@+id/game_exit" android:title="退出游戏" android:orderInCategory="2" app:showAsAction="always" /> </menu>
showAsAction="ifRoom"时的效果:(退出游戏显示不开被放到了菜单项中)
showAsAction="never"时的效果:(都被放到了菜单项中)
当未设置orderInCategory属性时,菜单列表上的每一项按从上往下的顺序排列:
<menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" tools:context=".OptionMenuActivity"> <item android:id="@+id/game_start" android:title="开始游戏" app:showAsAction="never" /> <item android:id="@+id/game_set" android:title="设置游戏" app:showAsAction="never" /> <item android:id="@+id/game_exit" android:title="退出游戏" app:showAsAction="never" /> </menu>
当设置orderInCategory属性时,菜单列表上的每一项按优先级排列(优先级从0开始,值越小优先级越高):
<menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" tools:context=".OptionMenuActivity"> <item android:id="@+id/game_start" android:title="开始游戏" android:orderInCategory="1" app:showAsAction="never" /> <item android:id="@+id/game_set" android:title="设置游戏" android:orderInCategory="0" app:showAsAction="never" /> <item android:id="@+id/game_exit" android:title="退出游戏" android:orderInCategory="2" app:showAsAction="never" /> </menu>
效果图如下:
2.Context Menu(上下文菜单)
(1)简介
(2)代码实现---ContextMenuActivity.class---menu_context.xml
public class ContextMenuActivity extends AppCompatActivity { private TextView changeColor; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_context_menu); changeColor = (TextView) findViewById(R.id.tv_change_color); //为TextView注册上下文菜单 registerForContextMenu(changeColor); } @Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { super.onCreateContextMenu(menu, v, menuInfo); //引入上下文菜单布局 getMenuInflater().inflate(R.menu.memu_context,menu); } @Override public boolean onContextItemSelected(MenuItem item) { int id = item.getItemId(); switch (id){ case R.id.red: changeColor.setBackgroundColor(Color.RED); break; case R.id.blue: changeColor.setBackgroundColor(Color.BLUE); break; case R.id.green: changeColor.setBackgroundColor(Color.GREEN); break; default: break; } return super.onContextItemSelected(item); } }
<menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" tools:context=".menu.ContextMenuActivity"> <item android:id="@+id/blue" android:title="蓝色" android:orderInCategory="1" /> <item android:id="@+id/red" android:title="红色" android:orderInCategory="0" /> <item android:id="@+id/green" android:title="绿色" android:orderInCategory="2" /> </menu>
(3)效果图:
3.Popup Menu(弹出式菜单)
(1)简介
(2)代码实现---PopupMenuActivity.class---menu_popup.xml
public class PopupMenuActivity extends AppCompatActivity { private Button btnClick; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_menu_popup); btnClick = (Button) findViewById(R.id.bt_click); } //按钮的点击事件 public void typeSize(View v){ //弹出式按钮 PopupMenu popupMenu =new PopupMenu(this,v); MenuInflater inflater = popupMenu.getMenuInflater(); inflater.inflate(R.menu.memu_popup,popupMenu.getMenu()); //设置监听事件 popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener(){ @Override public boolean onMenuItemClick(MenuItem item) { int id = item.getItemId(); switch (id) { case R.id.s: Toast.makeText(PopupMenuActivity.this, "你选择了S号", Toast.LENGTH_LONG).show(); break; case R.id.m: Toast.makeText(PopupMenuActivity.this, "你选择了号", Toast.LENGTH_LONG).show(); break; case R.id.l: Toast.makeText(PopupMenuActivity.this, "你选择了S号", Toast.LENGTH_LONG).show(); break; default: break; } return false; } }); popupMenu.show(); } }
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_context_menu" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.langdon.taiyang.androidtest.menu.PopupMenuActivity"> <Button android:id="@+id/bt_click" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="点我呀" android:onClick="typeSize"/> </RelativeLayout>
(3)效果