Material Design - Toolbar (二)

作者: Arnold_J | 来源:发表于2017-10-20 15:23 被阅读0次

    关键字:Toolbar、材料设计、ActionMenu
    项目地址:AboutMaterialDesign


    关于官方文档的介绍部分,我已经在上一篇写过,如果没有使用过 Toolbar 的话,可以先看看这篇:链接

    好,那么下面,我们接着之前的 ActionMenu 内容测试。
    先上几个效果图:


    GIF.gif 效果图.png

    一、测试效果1 - ActionMenuView

    GIF.gif

    这里主要有几个问题:

    • 首先是我遇到的:
      • 改变单个 item 默认宽度
      • 图片点击时,背景色变化的属性
      • 添加上述属性后,出现默认背景
      • menuItem 默认靠右
    • 其次是没有遇到,但是可能会有问题的
      • 布局是 上Toolbar 下LinearLayout,颜色浅的时候 toolbar 的 Z 轴可能会有比较明显的分割
      • 其他,忘了 = =

    1.1 正确显示 MenuItem
    • 首先,为了让 MenuItem 全部展示在 Toolbar 上面,我们需要在 menu.xml 中,把所有 item 的 showAsAction 属性设置为 always 。去掉设置在 Toolbar 中所有的视图,logo title subTitle 等等属性都应该从 xml 中剔除。然后我们会得到下面的效果:
    标题依旧存在
    • 好吧,上面的效果你可能复现不出来,因为不同的机型展示大概会不同,起码我这里确实是有两种情况。

    • 那么这里为什么已经去掉的 title 属性还是显示出来了呢?我们知道,如果不给 Toolbar 设置 title 那么 Toolbar 会自动获取 app_name 作为自己的 title。为此,我在 onCreate 中调用了 mToolbar.setTitle(null) 方法,但是结果并没有改变。

    通过一系列测试,我发现,这个获取 app_name 作为自己的 title 是在 onCreate - onResume 之间发生的,因此,我在 onResume 中调用了 mToolbar.setTitle(null) 期望能解决这个问题:

    @Override
    protected void onResume() {
        super.onResume();
        mToolbar.setTitle(null);
    }
    

    效果如下:


    效果图.png

    后来发现一个方法,不用在 onResume 里单独处理这个逻辑,放 onCreate 里就可以了,效果相同:

    getSupportActionBar().setDisplayShowTitleEnabled(false);//不显示title
    getSupportActionBar().setDisplayHomeAsUpEnabled(false);//不显示NavigationIcon
    getSupportActionBar().setDisplayShowHomeEnabled(false);//不显示logo
    
    • 现在我们已经去除了无用的视图,但是 MenuItem 还是默认靠右的布局,这一点在 Toolbar 中可以看到相关源码。这一点,我没有想到更聪明的办法。不过我没有选择反射,最终我决定自定义一个 ActionMenuView 放到 Toolbar 中去。可以代码动态构建,也可以直接放到 xml 中去。
    <android.support.v7.widget.Toolbar
        android:background="@color/colorPrimary"
        android:id="@+id/activity_test1_toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        app:title=""
        app:navigationIcon="@drawable/ic_back_light"
        app:popupTheme="@style/CustomPopupTheme"
        >
        <android.support.v7.widget.ActionMenuView
            android:id="@+id/activity_test1_toolbar_actionMenuViewId"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center"></android.support.v7.widget.ActionMenuView>
    </android.support.v7.widget.Toolbar>
    
    • 然后,在代码中,我们利用来动态更改 menu 的方法:
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        menu.clear();
        getMenuInflater().inflate(R.menu.menu_action2, mActionMenuView.getMenu());
        return super.onCreateOptionsMenu(mActionMenuView.getMenu());
    }
    
    效果图.png
    1.2 更改 MenuItem 默认宽度

    这个样式目前我只找到了一个有效属性 android:actionButtonStyle

    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    
    
        <item name="android:actionButtonStyle">@style/CustomActionButtonStyle</item>
    
    </style>
    
    <!-- Toolbar ActionButton 样式 -->
    <style name="CustomActionButtonStyle" parent="@android:style/Widget.Holo.ActionBar">
        <item name="android:minWidth">72dp</item><!-- 默认值 56 -->
        <item name="android:padding">0dp</item>
        <item name="android:background">@drawable/selector_bg_toolbar_action_btn</item>
    </style>
    
    效果图.png
    • 宽度已经更改成功了,但是新的问题出来了,我们发现图标多了一些东西。查看了一下代码,发现是 Widget.Holo.ActionBar 默认的背景图,包括上面一条灰色,下面一条蓝色,根据提示,找到了这个属性 android:background 顺便把点击效果也做了。
    <!-- Toolbar ActionButton 样式 -->
    <style name="CustomActionButtonStyle" parent="@android:style/Widget.Holo.ActionBar">
        <item name="android:minWidth">56dp</item><!-- 默认值 56 -->
        <item name="android:padding">0dp</item>
        <item name="android:background">@drawable/selector_bg_toolbar_action_btn</item>
    </style>
    
    • 不过奇怪的是,它只对我的 state_press 属性有响应, state_hovor state_focus 貌似没有


      GIF.gif

    二、测试效果2 - ActionLayout

    效果图.png

    我们知道,通常情况下, ActionMenu 在 Toolbar 中的作用是显示图片和文字。但是在很多时候,仅仅是图片文字,已经不能满足我们的需求,这个时候,我们需要 ActionLayout 这个属性,为我们导入自定义布局。

    例如上图,为一个嵌套在 Toolbar 中的 SearchView。图中除了箭头,其他全都是一个自定义 layout 布局的内容。
    附上 menu_action.xml 代码:

    <menu xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto">
        <item
            android:title="搜索框"
            android:id="@+id/menu_action_search"
            android:orderInCategory="1"
            app:showAsAction="always"
            app:actionLayout="@layout/layout_menu_search"
            />
    </menu>
    

    注意,这里 actionLayout 属性需要引用 app 下的标签,而不是 android 下的标签,否则无法按照视图内容显示。

    三、为什么我要去尝试 ActionMenu 实现这些效果

    如题,事实上,这些东西本没有必要。因为 Toolbar 本身是一个容器,对于自定义的布局,我们只需要将它自带的所有布局隐藏,然后把自己的布局添加进来就可以了。例如:

    <android.support.v7.widget.Toolbar
        android:id="@+id/activity_test2_toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        app:navigationIcon="@drawable/ic_back_light"
        android:background="@color/colorPrimary"
        >
    
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:text="title"
            android:textSize="20sp"
            android:textColor="@android:color/white"/>
        
    </android.support.v7.widget.Toolbar>
    
    

    但是,上面的方法写几个 demo 大概并没有什么问题,但是在一个庞大的工程里,通常没有办法这么容易地解决一个问题。我们更提倡动态地添加,更提倡新建和复用而不是修改原来的代码。对于同一个问题,我们期待自己拥有更多的解决方案来适应不同的场景。

    想努力让自己和自己的作品更好,想对每一行代码负责,想进步。

    带着这样的愿景,我在想要不要奖励自己一点什么。


    谢谢观赏

    相关文章

      网友评论

        本文标题:Material Design - Toolbar (二)

        本文链接:https://www.haomeiwen.com/subject/idumuxtx.html