美文网首页
Toolbar使用之正确姿势

Toolbar使用之正确姿势

作者: denglxsc | 来源:发表于2017-12-27 15:03 被阅读734次
    • 前言

    近期在公司做一个全新项目,自然在每个页面都有一个标题栏,脑海中涌出的第一想法肯定是采用Toolbar来实现,然后开始疯狂撸码,结果发现各种碰壁,比如:
    1.navigationIcon与左边的间距如何调整?
    2.title与navigationIcon间距如何调整?
    3.Toolbar中如何使用SearchView?
    4.SearchView如何自定义颜色图标文字等?
    ....
    带着这么多疑问开始各种查阅资料,然而里面好多问题之前都遇到并解决过,无奈又忘记了,老是花时间做重复的事情显得有些愚蠢,故抽时间将这些知识点整理一下,既方便自己后续查看也方便广大开发者可以有一个集中的参考。

    首先我们得知道ActionBar是Android 3.0的产物,Toolbar是Android 5.0的产物(我没记错吧?),因为ActionBar在国内各大厂商的定制系统下呈现出各种无法统一的效果,故Toolbar的出现,无疑是要一统江湖,取缔ActionBar。OK那就送走ActionBar。

    • 开发环境

    AndroidStudio 3.0.1

    • 各类控件所在包

    //均在appcompat包
    Toolbar:  android.support.v7.widget.Toolbar
    SearchView:  android.support.v7.widget.SearchView
    //添加依赖
    implementation 'com.android.support:appcompat-v7:26.1.0'
    
    //均在design包
    CollapsingToolbarLayout:  android.support.design.widget.CollapsingToolbarLayout
    AppBarLayout:  android.support.design.widget.AppBarLayout
    //添加依赖
    implementation 'com.android.support:design:26.1.0'
    
    • 新建项目默认样式

    用studio新建一个Empty Activity项目长这个样子的: image.png
    • 修改主题支持Toolbar

    默认Application主题的父亲是DarkActionBar,这样我们是不能直接在布局文件里面嵌套Toolbar的,否则会报错:

        <!-- Base application theme. -->
        <style name="CustomAppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
            <!-- Customize your theme here. -->
            <item name="colorPrimary">@color/colorPrimary</item>
            <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
            <item name="colorAccent">@color/colorAccent</item>
        </style>
    

    故,我要给它换一个爹: NoActionBar,这样便可以使用Toolbar:

        <!-- Base application theme. -->
        <style name="CustomAppTheme" 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>
        </style>
    

    点开NoActionBar看看里面的内容:

        <style name="Theme.AppCompat.Light.NoActionBar">
            <item name="windowActionBar">false</item>
            <item name="windowNoTitle">true</item>
        </style>
    

    再次运行App,效果如下!感觉秃了顶,太丑了!不能忍,绝对不能忍!!


    image.png

    我要给Ta添加一个Toolbar

    • 添加Toolbar

    修改布局文件,添加Toolbar控件,这里要注意单独使用Toolbar如果不添加背景色默认是无色的。

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@color/colorPrimary"
            android:minHeight="?attr/actionBarSize" />
    
    效果如图: image.png
    • 添加带阴影效果的Toolbar

    单纯使用Toolbar会发现下方并没有Z轴的阴影效果,想要有阴影效果,就得将Toolbar放入AppBarLayout中,如下:

    <android.support.design.widget.AppBarLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
    
            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:minHeight="?attr/actionBarSize" />
    
        </android.support.design.widget.AppBarLayout>
    
    看一下效果: image.png
    • 设置Toolbar返回箭头

            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:minHeight="?attr/actionBarSize"
                app:navigationIcon="@drawable/ic_arrow_back" />
    
    效果图
    • 调整Toolbar返回箭头左边距

    在styles.xml文件里添加下面属性:

        <!--ToolBar返回按钮间距-->
        <style name="ToolbarNavigationButtonStyle" parent="@style/Widget.AppCompat.Toolbar.Button.Navigation">
            <item name="android:minWidth">0dp</item>
            <item name="android:paddingLeft">12dp</item>
            <item name="android:paddingRight">12dp</item>
            <item name="android:scaleType">centerInside</item>
            <item name="android:tint">@android:color/white</item> <!-- 为返回icon着色 -->
        </style>
    
    然后再到AppTheme里引用该主题 image.png
    最终效果: image.png
    • 添加Toolbar标题

    image.png
    效果: image.png
    • 更改标题字体颜色

    styles.xml文件新建style

        <!--Toolbar标题样式-->
        <style name="ToolbarTitleStyle" parent="TextAppearance.Widget.AppCompat.Toolbar.Title">
            <item name="android:textColor">@android:color/white</item>
            <item name="android:textSize">18sp</item>
            <item name="android:textStyle">bold</item>
            <item name="android:gravity">center</item>
        </style>
    
        <!--Toolbar子标题样式-->
        <style name="ToolbarSubTitleStyle" parent="TextAppearance.Widget.AppCompat.Toolbar.Subtitle">
            <item name="android:textColor">@android:color/white</item>
            <item name="android:textSize">14sp</item>
            <item name="android:textStyle">normal</item>
            <item name="android:gravity">center</item>
        </style>
    
    在toolbar布局属性里添加 image.png
    效果 image.png
    • 设置Toolbar标题左边距

    用到的属性:contentInsetStartWithNavigation
    可在布局文件添加:app:contentInsetStartWithNavigation="0dp"
    亦可在styles.xml文件配置:

        <!--Toolbar样式总入口-->
        <style name="ToolbarStyle" parent="Widget.AppCompat.Toolbar">
            <item name="contentInsetStartWithNavigation">0dp</item> <!--设置标题距返回按钮间距-->
        </style>
    
    然后: image.png 效果: image.png

    其实这个0dp只是一个相对值,它有一个默认最小值,经过我的测试,在52以下,随便设置多少,它都是显示的最小值,大于52则逐渐增加(实际不会谁设计间距这么大,顶多是居中罢了)

    • 设置Toolbar标题剧中

    貌似Toolbar并没有直接可以设置标题居中显示的属性及api,又因Toolbar实际是个ViewGroup,故在其内部嵌套一个TextView实现居中显示标题

     <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:minHeight="?attr/actionBarSize"
                app:navigationIcon="@drawable/ic_arrow_back">
    
                <TextView
                    android:id="@+id/tv_title"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    android:text="Title"
                    android:textAppearance="@style/ToolbarTitleStyle" />
            </android.support.v7.widget.Toolbar>
    
    效果如图: image.png
    • Toolbar添加menu

    在res文件夹下新建menu目录,在该目录内新建menu文件

    <menu xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto">
    
        <item
            android:id="@+id/action_search"
            android:icon="@drawable/ic_search"
            android:title="Search"
            app:showAsAction="always" />
    
        <item
            android:id="@+id/action_add"
            android:orderInCategory="101"
            android:title="添加"
            app:showAsAction="never" />
    
        <item
            android:id="@+id/action_del"
            android:orderInCategory="102"
            android:title="删除"
            app:showAsAction="never" />
    
        <item
            android:id="@+id/action_share"
            android:orderInCategory="100"
            android:title="分享"
            app:showAsAction="never" />
    
    </menu>
    

    在Activity中重写以下方法加载menu文件

        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            getMenuInflater().inflate(R.menu.menu_do_actions, menu);
            return super.onCreateOptionsMenu(menu);
        }
    

    如果运行无效果,请确保是否初始化Toolbar

            Toolbar toolbar = findViewById(R.id.toolbar);
            toolbar.setTitle("");
            setSupportActionBar(toolbar);
            toolbar.setNavigationOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
    
                }
            });
    
    效果如图: image.png

    啧啧啧,黑黢黢的,真TM丑。。。

    • Toolbar中menu图标&样式修改

    或许将menu中的图标或者是文字变成白色会好看些吧

    方法一:
    将menu中文字变成白色,在app主题中加入如下属性: image.png 如图: image.png
    将右边三点变成白色,同样在主题中加入一条属性: image.png
    如图: image.png
    方法二:

    通过配置Toolbar主题改变图标文字颜色
    在布局文件中加入属性:android:theme="@style/ToolbarTheme"
    在styles.xml文件新建style

        <!--Toolbar主题配置-->
        <style name="ToolbarTheme" parent="@style/ThemeOverlay.AppCompat.ActionBar">
            <item name="android:textSize">16sp</item> <!-- menu字号 -->
            <item name="android:textStyle">bold</item><!-- menu粗体 -->
            <item name="actionMenuTextColor">@android:color/white</item> <!-- menu字体颜色,不要加android前缀,否则4.4以前无效 -->
            <item name="android:textColorPrimary">@android:color/holo_red_light</item> <!-- 改变menu图标及隐藏菜单字体颜色 -->
        </style>
    
    此方法会改变menu中图标和never属性菜单的字体颜色: overflowmenu.gif
    • Toolbar中放入SearchView

    在menu菜单中加入:

        <item
            android:id="@+id/action_search"
            android:title="搜索"
            app:showAsAction="always"
            app:actionViewClass="android.support.v7.widget.SearchView" />
    

    再将ToolbarTheme里面这条属性修改为白色
    <item name="android:textColorPrimary">@android:color/white</item>
    效果貌似还不错:

    GIF.gif
    • 修改SearchView的hint文字和颜色

    首先要得到SearchView,再调用api设置

        private SearchView mSearchView;
        private SearchView.SearchAutoComplete mSearchAutoComplete;
    
            @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            getMenuInflater().inflate(R.menu.menu_do_actions, menu);
            MenuItem searchItem = menu.findItem(R.id.action_search);
            mSearchView = (SearchView) searchItem.getActionView();
            mSearchAutoComplete = mSearchView.findViewById(R.id.search_src_text);
    //        mSearchView.setIconified(false); //默认打开搜索框
            //设置Hint文字颜色
            mSearchAutoComplete.setHintTextColor(ContextCompat.getColor(this,android.R.color.darker_gray));
            //设置输入文字颜色
            mSearchAutoComplete.setTextColor(ContextCompat.getColor(this,android.R.color.white));
            //设置Hint文字
            mSearchView.setQueryHint("Hint text here");
            //设置是否显示搜索框展开时的提交按钮
            mSearchView.setSubmitButtonEnabled(false);
            return super.onCreateOptionsMenu(menu);
        }
    
    效果图: gif001.gif
    • 设置SearchView搜索监听

    SearchView输入内容监听

            mSearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
                @Override
                public boolean onQueryTextSubmit(String query) {
                    return false;
                }
    
                @Override
                public boolean onQueryTextChange(String newText) {
                    // TODO: 处理一些输入内容改变的逻辑 
                    return false;
                }
            });
    

    SearchView关闭按钮监听

            mSearchView.setOnCloseListener(new SearchView.OnCloseListener() {
                @Override
                public boolean onClose() {
                    // TODO: 处理一些关闭搜索框后的逻辑,比如还原之前数据 
                    return false;
                }
            });
    

    NavigationClickListener关联SearchView,当输入框展开时,点击返回是关闭输入框,否则是关闭当前页面

            toolbar.setNavigationOnClickListener(v -> {
                if (mSearchAutoComplete.isShown()){
                    try {
                        //如果展开则先关闭搜索框
                        mSearchAutoComplete.setText("");
                        Method method = mSearchView.getClass().getDeclaredMethod("onCloseClicked");
                        method.setAccessible(true);
                        method.invoke(mSearchView);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }else{
                    finish();
                }
            });
    
    效果图: gif002.gif

    如有不完善或者错误之处,希望多多指正。

    相关文章

      网友评论

          本文标题:Toolbar使用之正确姿势

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