首页 > 代码库 > Menu与ActionBar的爱恨情仇

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)效果

  技术分享

    

 

Menu与ActionBar的爱恨情仇