Android中menu的使用集锦

2018-04-22  本文已影响0人  笔墨Android
image

最近在研究关于MaterialDesign系类的内容,在研究Toolbar和NavigationView的时候,都使用到menu的内容。感觉自己不是很理解,可以说就是不知道,只会简单的写一个menu其他的什么都不会了。所以总结一下,希望对大家有帮助!!!

本文会讲解的知识点

1. menu的使用

首先说明一下menu的存放位置,在创建项目的时候,是没有menu文件夹的,所以这里你要自己创建一个menu文件夹,然后新建一个menu文件。具体位置看下面这张图就可以了(因为这张图设置了相应的样式,所以弹出来的popup有一个背景色)!

menu文件的位置

下面我们来介绍关于menu文件怎么写,以及各个属性的含义

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <item
        android:id="@+id/menu_search"
        android:icon="@drawable/ic_search_black_24dp"
        android:title="搜索"
        app:actionViewClass="android.widget.SearchView"
        app:showAsAction="ifRoom" />
    <item
        android:id="@+id/menu_cycling"
        android:icon="@mipmap/ic_directions_bike_white_24dp"
        android:title="去知乎的Toolbar"
        app:showAsAction="ifRoom" />
    <item
        android:id="@+id/menu_other"
        android:title="去网易云音乐的ToolBar"
        app:showAsAction="never" />

    <item
        android:id="@+id/menu_more"
        android:title="更多">
        <menu>
            <item
                android:id="@+id/menu_more1"
                android:title="更多1" />
            <item
                android:id="@+id/menu_more2"
                android:title="更多2" />
            <item
                android:id="@+id/menu_more3"
                android:title="更多3" />
        </menu>
    </item>

</menu>

这是一个比较复杂的menu文件了,对于一般的menu不会有下面更多的那个item。还是先看一下效果吧!

多层的menu文件的显示

看了效果之后,我们就很好理解其中的属性了,这里先解释一下相应的menu标签的属性值:

2. menu的属性说明

2.1 item的属性说明

这里面的属性很多,但是个人觉得有很多用不上,列出来的都是一些常用的属性。

2.2 group的属性说明

主要是一个组的属性,和RadioGroup的样式类似,主要是实现复选的!里面的一些属性和上面是类似的,这里主要说明一个属性

下面是关于group标签的使用

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <item
        android:id="@+id/app_bar_search"
        android:icon="@drawable/ic_search_black_24dp"
        android:title="Search"
        app:actionViewClass="android.widget.SearchView"
        app:showAsAction="always" />
    <item
        android:id="@+id/menu_delete"
        android:icon="@mipmap/ic_delete"
        android:title="删除"
        app:showAsAction="always|collapseActionView">

        <menu>
            <group android:checkableBehavior="all">
                <item android:title="group1" />
                <item android:title="group2" />
                <item android:title="group3" />
            </group>
        </menu>
    </item>
    <item
        android:id="@+id/menu_setting"
        android:icon="@mipmap/ic_delete"
        android:title="设置"
        app:showAsAction="ifRoom" />
    <item
        android:id="@+id/menu_other"
        android:icon="@mipmap/ic_delete"
        android:title="不知道什么"
        app:showAsAction="ifRoom" />
</menu>

这里就是通过自定义溢出菜单展示的group,具体效果看下面这张图

group的展示

设置menu二级菜单的时候(无论是自定义还是系统的),前一级标签的文字颜色是黑色的,这个目前还没有找到好的解决方案,希望知道的给留个言!!!谢谢

3. menu的使用注意事项

这里我主要像说明一下我在开发中遇到的关于menu的一些问题

这些问题,在平时的开发中,相信很多人都不会注意到!所以这里有必要和大家分享一下相关的内容。

3.1 Fragment中怎么显示menu?

Fragment中显示menu文件和Activity中是类似的,但是必须在挂在View之前添加setHasOptionsMenu(true);这句代码(基本上都是加载onCreat()上面),否则显示不出来的。。。

public class Main1Fragment extends Fragment {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setHasOptionsMenu(true);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_main1, container, false);
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        inflater.inflate(R.menu.menu_main_fragment1, menu);
    }
}

上面这段代码就是Fragment中显示menu的方法!

3.2 Activity和Fragment同时使用menu会怎样显示?

是不是觉得很奇怪的问题,你的答案是什么?是不是变得模棱两可了,其实有的面试官很关注这些细节。答案就是叠加显示,怎么个叠加显示呢?一个简单的说明,你在Activity中添加了一个设置的menu条目,如果你在Fragment中也写了一个,那么menu上会新增一个Fragment的menu文件。


就像这样

3.3 Activity和Fragment同时处理点击事件怎么相应?

有的人可能会问了,那点击事件怎么处理呢?其实处理起来很简单,就是在onOptionsItemSelected处理相应的点击事件。但是有一个点需要注意,就是Activity的onOptionsItemSelected方法的返回值!默认的情况下应该返回super.onOptionsItemSelected(item)这个,防止处理了事件之后,Fragment收不到相应的点击事件!

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.menu_setting:
                Log.e(TAG, "onOptionsItemSelected: setting");
                return true;
            case R.id.menu_other:
                Log.e(TAG, "onOptionsItemSelected: other" );
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.fragment1:
                Log.e(TAG, "onOptionsItemSelected: fragment1" );
                return true;
            case R.id.fragment2:
                Log.e(TAG, "onOptionsItemSelected: fragment2" );
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }

这样所有的点击事件就能得到相应的响应了。

3.4 menu的怎么动态改变?

有的人可能说动态的刷新了menu但是却没有成功,其实是没有调用invalidateOptionsMenu();通知menu刷新的方法造成的。下面我们来看看menu刷新的代码:

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.fragment1:
                Log.e(TAG, "onOptionsItemSelected: fragment1");
                isRefeesh = true;
                getActivity().invalidateOptionsMenu();
                return true;
            case R.id.fragment2:
                Log.e(TAG, "onOptionsItemSelected: fragment2");
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }

    @Override
    public void onPrepareOptionsMenu(Menu menu) {
        MenuItem item = menu.findItem(R.id.fragment1);
        if (isRefeesh) {
            item.setTitle("刷新后的fragment1");
        } else {
            item.setTitle(item.getTitle());
        }
    }

这里说一下相应的逻辑,当调用invalidateOptionsMenu();的时候会重走onPrepareOptionsMenu这个方法,这里我用了一个标识去标记是否刷新,为什么会有这个标识呢?因为onPrepareOptionsMenu准备menu的时候调用,所以刚一进来的时候就会被调用一次,点击后还会调用一次。

3.5 多个Activity同时使用一个menu怎么简化操作?

这个相当于继承的关系。其实这个问题也是相应的叠加问题,只要你记住menu是可以叠加的就可以。只要在你的onCreateOptionsMenu方法中加载父类的menu就可以了,像下面面这样!

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    super.onCreateOptionsMenu(menu);//调用这一句保证父类的菜单项可以正常加载
    getMenuInflater().inflate(R.menu.menu_main_fragment,menu);//加载子类自己的菜单项
    return true;
}

基本上关于menu的使用就这些了,总结的可能还会有不到位的地方,如果你还有关于menu的使用问题,可以给我留言。

上一篇下一篇

猜你喜欢

热点阅读