Android中menu的使用集锦

image

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

本文会讲解的知识点

  • menu的使用
  • 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的属性说明

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

  • android:id 控件的ID
  • android:icon 空间的图标(这里如果显示在Toolbar上面,会显示图片,在溢出菜单里面的话会只显示文字)
  • android:title 显示的标题(也就是条目的内容)
  • app:actionViewClass 引入一个View(这个是在实现搜索的时候用到的)
  • app:showAsAction 显示方式
    • ifRoom 如果有空间的话,会显示在ToolBar上,当空间不足的时候会显示在列表中
    • always 一直显示在ToolBar上(如果没有空间的话,还是会显示在列表中,按先后顺序排列的)
    • collapseActionView (一般要配合ifRoom一起使用)声明这个操作视窗应该被折叠到一个按钮中,当用户选择这个按钮时,这个操作视窗展开。这个属性主要是实现自意义溢出菜单的。可以在它的里面设置一些item从而实现溢出菜单(这个自定义的溢出菜单和默认的溢出菜单唯一的区别就是它可以显示图标)
    • never 不会显示在Toolbar上面,会显示在列列表中
    • withText 表示显示的时候如果空间足够,会显示menu的title。但是我试了试没看到,还请知道的大神告知一声!
  • android:titleCondensed 当你设置的内容过长的时候,可以使用这个属性进行简短的说明
  • android:onClick 和View的onClick方法类似,设置一个点击事件
  • android:checkable 菜单是否可以复选,如果可以复选的话设置成true
  • android:checked 菜单是否可以被选中,如果可以被选中的话设置成true
  • android:visible 菜单是否显示
  • android:enabled 菜单项目是否可用,如果可用为true。主要是用在自定义溢出菜单的时候,是否可以进行相应的相应。
  • android:orderInCategory 菜单的优先级,整数类型,数字越小越靠前

2.2 group的属性说明

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

  • android:checkableBeharior 设置复选行为的类型
    • none 没有可复选性
    • all 组内的所有的项目都可以被复选(使用复选框)
    • single 仅有一个项目能够被复选(使用单选按钮)

下面是关于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的一些问题

  • Fragment中怎么显示menu?
  • Activity和Fragment同时使用menu会怎样显示?
  • Activity和Fragment同时处理点击事件怎么相应?
  • menu的怎么动态改变?
  • 多个Activity同时使用一个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收不到相应的点击事件!

  • Activity的onOptionsItemSelected方法:
    @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);
        }
    }
  • Fragment的onOptionsItemSelected方法:
    @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的使用问题,可以给我留言。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,980评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,178评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,868评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,498评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,492评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,521评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,910评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,569评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,793评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,559评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,639评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,342评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,931评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,904评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,144评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,833评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,350评论 2 342

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,376评论 25 707
  • 我读书挺慢的,三天读完冯唐的《三十六大》,还是在学院办公室做助管的时候读完的,办公室没有事情的时候,我就拿出绿色封...
    李旭洋阅读 314评论 0 0
  • 我反复推敲 自己来的早还是晚 亦或是正当时 在它盛妆将卸时到场 我早忘了将它放在梦里 兀自地它开在梦外 谢场也在梦...
    永远的清湄阅读 234评论 4 2
  • 连续五天跟随长安老师的阿奴萨拉瑜伽习练集训结束了。作为一个有四五年瑜伽习练经验的老人来说,这是一个从内进行自我打破...
    木鱼78阅读 209评论 1 2
  • 阳光灿烂的日子 风儿轻佛脸颊 树上的鸟儿 还在叽叽渣渣 树下的老人 睡得正香 一丝微笑还挂在嘴角 梦中 又至除夕 ...
    幽幽墨香阅读 166评论 4 5