澳门新葡萄京官网注册 13

最详细的 Android Toolbar 开发实践总结

度岁前发了一篇介绍 Translucent System Bar 个性的小说 Translucent System
Bar 的顶级执行
,收到众多开辟者的关怀和申报。后天起头写第二篇,周详的牵线一下
Toolbar 的使用。说起 Toolbar
,或然有多数开荒的童鞋还比较素不相识,没涉及,请接着往下看。

背景

近期刚上学完android相关的根底摄像,尝试着在github找出一些类别练练手,fork了一个girls(相信我绝对是宅男的最爱)项目,发现activity_main.xmldrawerlayout很有意思,继续深刻,发未来其子构造中有个Toolbar挺新鲜的布局也很为难,就想立刻尝试自个儿用用那么些控件,在掘金(强烈推荐,干货大大的有)找到了Android开采:最详尽的
Toolbar
开采执行计算那篇作品,评价嘛,讲的很好,可是不知情多少个点(下文便是)就极其girls来用轮子,后果就是浪费广大岁月,一直达预期的效应。待笔者细细道来

ps : 以Android开采:最详尽的 Toolbar
开采推行计算那篇随笔为底子框架

  • 协作作者下边讲的多少个知识点和,toolbar用的溜起来。

初识 Toolbar

Toolbar是在 Android 5.0 初始要推荐出的一个 Material Design 风格的领航控件
,Google 特别推荐咱们使用 Toolbar
来作为Android客商端的导航栏,以此来取代在此以前的 Actionbar 。与
Actionbar 相比, Toolbar 显明要灵活的多。它不像 Actionbar
同样,一定要固定在Activity的顶端,而是能够停放分界面包车型大巴大肆地点。除外,在设计
Toolbar
的时候,谷歌(GoogleState of Qatar也留给了开荒者比较多可定制校勘的后路,那个可定制改良的性质在API文书档案中都有详实介绍,如:

  • 安装导航栏图标;
  • 设置App的logo;
  • 援救设置标题和子标题;
  • 支撑增加八个或几个的自定义控件;
  • 支持Action Menu;

澳门新葡萄京官网注册 1

Toolbar辅助的特征

总之,与 Actionbar 相比, Toolbar
让本人感触到Google满满的红心。怎样?是还是不是曾经对 Toolbar
有大致的垂询,一触即发的痛感出来了有木有?接下去,大家就一步一步的来看怎么样接纳
Toolbar (其实是自家动用 Toolbar
踩坑填坑的血泪史,你们接下去看,笔者先擦个眼泪…. )。

填坑

  1. #### Toolbar效果图

澳门新葡萄京官网注册 2

toolbar.gif

早先接收 Toolbar

前面提到 Toolbar 是在 Android 5.0 才起先加多的,Google为了将这一设计向下包容,自然也至关重要要搞出宽容版的 Toolbar
。为此,大家必要在工程中引进 appcompat-v7 的十二分包,使用
android.support.v7.widget.Toolbar
举办开采。下边看一下代码布局,相通把重当先十分之五已经红圈圈出:

澳门新葡萄京官网注册 3
关键部分代码

  • ToolbarActivity 包含了 Toolbar 的片段为主采取, ZhiHuActivity
    是在熟识了 Toolbar 后对天涯论坛主页面包车型大巴一个高仿达成。
  • layout和menu文件夹分别是地点提到的四个Activity的布局文件 和
    actionmenu 菜单文件。
  • values、values-v19、values-v21 中富含了有个别自定义的
    theme,前面用到的时候会顺便批注。

大家先来看一下 ToolbarActivity 的运维作效果果

澳门新葡萄京官网注册 4

ToolbarActivity效果图

信守效果与利益图,从左到右分别是咱们最近提起到的 导航栏Logo
App的logo标题和子标题自定义控件 、以及
ActionMenu 。接着,我们来看下结构文件和代码完毕。

第一,在构造文件 activity_tool_bar.xml 中增加进大家须求的 Toolbar 控件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/color_0176da">

        <!--自定义控件-->
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Clock" />
    </android.support.v7.widget.Toolbar>
</LinearLayout>

接着在 base_toolbar_menu.xml 中添加 action 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/action_search"
        android:icon="@mipmap/ic_search"
        android:title="@string/menu_search"
        app:showAsAction="ifRoom" />

    <item
        android:id="@id/action_notification"
        android:icon="@mipmap/ic_notifications"
        android:title="@string/menu_notifications"
        app:showAsAction="ifRoom" />

    <item
        android:id="@+id/action_item1"
        android:title="@string/item_01"
        app:showAsAction="never" />

    <item
        android:id="@+id/action_item2"
        android:title="@string/item_02"
        app:showAsAction="never" />
</menu>

最后到 ToolbarActivity 中调用代码得到那 Toolbar
控件,并在代码中做种种setXXX操作。

/**
 * Toolbar的基本使用
 */
public class ToolBarActivity extends BaseActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_tool_bar);

        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);

        toolbar.setNavigationIcon(R.mipmap.ic_drawer_home);//设置导航栏图标
        toolbar.setLogo(R.mipmap.ic_launcher);//设置app logo
        toolbar.setTitle("Title");//设置主标题
        toolbar.setSubtitle("Subtitle");//设置子标题

        toolbar.inflateMenu(R.menu.base_toolbar_menu);//设置右上角的填充菜单
        toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
            @Override
            public boolean onMenuItemClick(MenuItem item) {
                int menuItemId = item.getItemId();
                if (menuItemId == R.id.action_search) {
                    Toast.makeText(ToolBarActivity.this , R.string.menu_search , Toast.LENGTH_SHORT).show();

                } else if (menuItemId == R.id.action_notification) {
                    Toast.makeText(ToolBarActivity.this , R.string.menu_notifications , Toast.LENGTH_SHORT).show();

                } else if (menuItemId == R.id.action_item1) {
                    Toast.makeText(ToolBarActivity.this , R.string.item_01 , Toast.LENGTH_SHORT).show();

                } else if (menuItemId == R.id.action_item2) {
                    Toast.makeText(ToolBarActivity.this , R.string.item_02 , Toast.LENGTH_SHORT).show();

                }
                return true;
            }
        });

    }

}

代码到此已经实现了 Toolbar
的着力使用,注意,是着力采纳而已!!!!!下边有多少个代码里面必要小心的地点:

  1. 我们在行使 Toolbar
    时候需求先隐瞒掉系统本来的导航栏,英特网海人民广播广播台湾大学人都在说给Activity设置一个NoActionBar的Theme。但个人感觉多少小题大作了,所以那边小编一贯在BaseActivity中调用
    supportRequestWindowFeature(Window.FEATURE_NO_TITLE)去掉了暗中认可的导航栏(注意,小编的BaseActivity是世袭了AppCompatActivity的,假诺是世襲Activity就应当调用
    requestWindowFeature(Window.FEATURE_澳门新葡萄京官网注册 ,NO_TITLE) );
  2. 只要您想校正题目和子题指标字体大小、颜色等,能够调用
    setTitleTextColorsetTitleTextAppearance
    setSubtitleTextColorsetSubtitleTextAppearance 这些API;
  3. 自定义的View坐落于 titlesubtitleactionmenu
    之间,那意味着,要是 titlesubtitle 都在,且
    actionmenu选项 太多的时候,留给自定义View的长空就越小;
  4. 导航Logo和 app logo 的分别在哪?借令你只设置 导航Logo ( or
    app logo ) 和 titlesubtitle ,会发现 app logo
    titlesubtitle 的间距相当小,看起来不及 导航空Logo
    与 它们两搭配雅观;
  5. Toolbar和其余控件相似,超多质量设置格局既支持代码设置,也扶持在xml中装置(这里也是最最最最最坑爹的地点,如何坑爹法,请接着往下看);

Actionbar效果图

澳门新葡萄京官网注册 5

actionbar.png

Toolbar 踩坑填坑

坑一:xml结构文件中,Toolbar属性设置无效

刚初阶利用Toolbar的时候,作者的构造文件中是那般写的

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/color_0176da"
        android:logo="@mipmap/ic_launcher"
        android:navigationIcon="@mipmap/ic_drawer_home"
        android:subtitle="456"
        android:title="123">

        <!--自定义控件-->
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Clock" />
    </android.support.v7.widget.Toolbar>
</LinearLayout>

在真机跑起来今后,见到的结果是下面那样的。

澳门新葡萄京官网注册 6

Toolbar 属性设置无效

那会儿心里真是万千匹草泥马在跑马,除了安装背景色和TextView有效外,说好的
logonavigationIconsubtitletitle
都跑哪去了?在编写翻译器没报错又不见到效果果的情形下,参谋了此外开荒者的用法后找到了以下的解决方案,就是在根构造中参与自定义属性的命名空间

xmlns:toolbar="http://schemas.android.com/apk/res-auto"(这里的toolbar可以换成你想要其他命名,做过自定义控件的童鞋相比很熟悉此用法了)

然后把全部用 android:xxx 设置无效的,都用 toolbar:xxx
设置就能够以看到到效果。最后的布局代码如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:toolbar="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/color_0176da"
        toolbar:navigationIcon="@mipmap/ic_drawer_home"
        toolbar:logo="@mipmap/ic_launcher"
        toolbar:subtitle="456"
        toolbar:title="123">

        <!--自定义控件-->
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Clock" />
    </android.support.v7.widget.Toolbar>
</LinearLayout>

到此就能够解决 xml
中品质设置失效的主题素材,为啥会并发这种难点吧?作者嫌疑是因为那个控件是宽容版的控件,用
android:xxx 设置无效是的那个属性是在特别包中,不在暗中同意的Android
SDK中,所以我们需求特其余引进。至于为何IDE不报错,估量便是bug了吧!

坑二:Action Menu Item 的文字颜色设置无效

系统默设置了ActionMenu每一种Item的文字颜色和尺寸,像ToolbarActivity在谷歌(Google卡塔尔国原生5.1系列下暗许效果就是底下那样的

澳门新葡萄京官网注册 7

Android 5.1 默认的ActionMenu Item的风格

这个时候,假若自身有需求要转移一下item文字颜色,应该怎么破?我遵照网络相比分布的缓慢解决方案,做了之类两步的退换操作:

在styles.xml中自定义三个Theme,并设置 actionMenuTextColor
属性(注意:不是 android:actionMenuTextColor )

<style name="Theme.ToolBar.Base" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="actionMenuTextColor">@color/color_red</item>
</style>

在布局文件的Toolbar中设置popupTheme(注意:是toolbar:xxx,不是android:xxx)

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/color_0176da"
        toolbar:popupTheme="@style/Theme.ToolBar.Base">

        <!--自定义控件-->
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Clock" />
    </android.support.v7.widget.Toolbar>

运营之后,文字的颜色的并从未生出任何改造。说好的更正颜色吗…..找来找去,最后再
StackOverflow 找到三个还不易的解决方案,就是把地点的的
actionMenuTextColor 属性换到 android:textColorPrimary
就能够解决,最后得到上面包车型的士运作效果。

澳门新葡萄京官网注册 8

大功告成纠正 actionmenu item 文字的颜料

这种方式也会有八个小缺欠,假使自己把自定义控件换成Button,你会意识Button私下认可的文字颜色也化为了新民主主义革命。所以,此处要是有朋友有更加好的解决方案,请留言赐教。

假定你想要更改 ActionMenu Item
的文字大小,也能够在theme中安装增添如下设置

<item name="android:textSize">20sp</item>

以上正是日前使用 Toolbar 一些对比折腾的坑,认为 谷歌(Google卡塔尔国 对
Toolbar 这几个坑,还是可以越发优化优化,不然就坑苦了开辟者们了。

2. 第一坑: setSupportActionBar(mToolbar);

意味着:让toolbar同actionbar相通采纳,那句话最伊始本身也是生搬硬套,现在回首要清楚那句话的关键在于先明白Actionbar。并且自个儿还做了叁个干活正是把Toolbar与Actionbar举行了对待,在进行详细解析。

Actionbar参照链接

仿乐乎主页面

为了加强一下 Toolbar 的开支体验,我们使用 Toolbar
来达成搜狐主页的功能!先来看下和讯主页的效应

澳门新葡萄京官网注册 9

Android 5.1上今日头条主页效果图

借使前方的内容你看精通,想撸出这么些分界面无非是几分钟的业务,上边就径直上代码,不做赘述了。

ZhiHuActivity分界面代码

public class ZhiHuActivity extends BaseActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_zhi_hu);

        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        toolbar.inflateMenu(R.menu.zhihu_toolbar_menu);

        toolbar.setNavigationIcon(R.mipmap.ic_drawer_home);

        toolbar.setTitle(R.string.home_page);
        toolbar.setTitleTextColor(getResources().getColor(android.R.color.white));
    }
}

zhihu_toolbar_menu.xml 菜单

<?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/action_search"
        android:icon="@mipmap/ic_search"
        android:title="@string/menu_search"
        app:showAsAction="ifRoom" />

    <item
        android:id="@id/action_notification"
        android:icon="@mipmap/ic_notifications"
        android:title="@string/menu_notifications"
        app:showAsAction="ifRoom" />

    <item
        android:id="@id/action_settings"
        android:orderInCategory="100"
        android:title="@string/menu_settings"
        app:showAsAction="never" />

    <item
        android:id="@id/action_about"
        android:orderInCategory="101"
        android:title="@string/menu_about_us"
        app:showAsAction="never" />
</menu>

activity_zhi_hu.xml 布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/color_0176da"
        android:theme="@style/Theme.ToolBar.ZhiHu">

    </android.support.v7.widget.Toolbar>

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@android:color/white">

        <ImageView
            android:layout_width="60dp"
            android:layout_height="60dp"
            android:layout_centerInParent="true"
            android:background="@mipmap/ic_zhihu_logo" />
    </RelativeLayout>

</LinearLayout>

styles.xml 中的 Theme.ToolBar.ZhiHu,给 Toolbar
设置android:theme用的

<resources>

    ...
    ...

    <style name="Theme.ToolBar.ZhiHu" parent="Theme.AppCompat.Light.NoActionBar">
        <item name="actionOverflowButtonStyle">@style/ActionButton.Overflow.ZhiHu</item>
    </style>

    <style name="ActionButton.Overflow.ZhiHu" parent="android:style/Widget.Holo.Light.ActionButton.Overflow">
        <item name="android:src">@mipmap/ic_menu_more_overflow</item>
    </style>

</resources>

末尾收获下边那样的功力

澳门新葡萄京官网注册 10

Android5.1上仿微博主页面效果

这里在 Toolbar 设置 android:theme=”@style/Theme.ToolBar.ZhiHu”
首假设为着替换系统右上角四个点的Logo,假诺不安装,则会成系列暗许主旨的模范。

澳门新葡萄京官网注册 11

不设置Theme的效果

终极,再给微博的主页面做个小小的的优化,它在 Android 4.4
上运营还能够看出一条黑忽忽的公告栏,为此我把 Toolbar
Translucent System Bar 的特色结合起来,最后改进成上面包车型客车效果(附上
Android4.4 和 5.1 上的运作效果)。

澳门新葡萄京官网注册 12

Android4.4上修改版的乐乎主页

澳门新葡萄京官网注册 13

Android5.1上修改版的和讯主页

倘若您还不晓得 Translucent System Bar
的特点怎么选用,请查看自个儿的上一篇文章: Translucent System Bar
的顶级执行

2.1Actionbar与Toolbar的对比
Item Actionbar Toolbar
生产时间 Android 3.0 Android5.0
荧屏的任务 只可以在顶上部分(状态栏下方卡塔尔(قطر‎ 任意
Logo设置

暗中同意情状下,系统会利用manifest.xml中<application>或者<activity>中android:icon品质钦赐的图纸来作为ActionBar的Logo,不过大家也能够校正这一默许行为。一经我们想要使用别的一张图片来作为ActionBar的Logo,也得以因而android:logo天性来张开点名|
能够在xml 中** toolbar:logo(特别注意)/
在MainAcitivity.java中
toolbar.setlogo** |
| Title的设置 | 默认在manifest.xml
<application/<activity>中的android:lable属性| 可以在xml
中** toolbar:title(特别注意)/
在MainAcitivity.java中
toolbar.setTitle** |
|导航空Logo|在.java文件中调用**
actionBar.setDisplayHomeAsUpEnabled()主意来启用ActionBarLogo导航功用,况兼Logo准样板式单一只有<(类似back键)|可以在xml
自定义各类图标; toolbar:navigationIcon(特别注意)/
在MainAcitivity.java中
toolbar.setnavigationIcon|
|ActionMenu | MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main, menu) | 添加menu文件+
toolbar.inflateMenu(R.menu.zhihu_toolbar_menu);|
|自定义控件|不能|能够加上
自定义控件** 如上海教室中的Clock|
|自定义Subtitle|不能够|能够加上自定义subtitle 如上航海用教室中的subtitle|

总结:

对待剖析发现: toolbar
要比actionbar使用更加灵敏,在自定义Logo、自定义Title、导航空Logo,以致不过优良的在自定义控件和subtitle时(toolbar
可以/actionbar不行)

总结

关于 Toolbar
的运用就介绍到此,本来是满怀相当轻巧就能够上手的心怀来选拔,结果开掘照旧有好些个坑必要填。果然依旧印证了一句老话

纸上得来终觉浅,绝知此事要躬行

对此想要越来越深的询问 Toolbar 设计的童鞋,也足以看看那篇
官方网站文书档案
(自备梯子)。

一模一样,分享即美德,需求源代码的童鞋,请戳:

2.2 setSupportActionBar(mToolbar)的误用

此前面包车型大巴知识点领悟能够,当.java代码中参与了setSupportActionBar(mToolbar)表示让Toolbar
当做Actionbar使用,若那个时候现身如下代码:

走过的代码坑

@requires_authorization     
       setSupportActionBar(toolbar);//表示让toolbar同actionbar一样使用     
        toolbar.setTitle("首页");
        toolbar.setNavigationIcon(R.drawable.toolbar_nav);
        toolbar.setNavigationOnClickListener(new View.OnClickListener() 

得到的功力:看不到导航空Logo,看不到菜单,看不到ActionMenu 。why ? ?
?
答: 因为
setSupportActionBar(toolbar卡塔尔;就曾经代表让toolbar当actionbar使用,而actionbar不协助在.java代码中插手如
toolbar.setTitle(“首页”卡塔尔(قطر‎的代码
Actionbar的Title在manifest中用android:lable指定

** 猛烈提醒:

setSupportActionBar(toolbarState of Qatar;//表示让toolbar同actionbar相似接纳
toolbar.setTitle(“首页”);
toolbar.setNavigationIcon(R.drawable.toolbar_nav);

无法一同用

3. 第二坑:fitsSystemWindow=true;

copy过来的layout开掘成数不清地方都用到了**fitsSystemWindow=true;
**那条语句,本身也拿来模拟用,发掘标题一箩筐,究其原因——对那条代码不了然。

翻看资料表明:

作用:是让view可以依照系统窗口来调动和睦的构造,若为true,就能够调解这些**view的paddingTop属性
**来给System Window留出空间。
系统窗口:System windows 指的就是显示屏上status bar、 navigation
bar等系统控件所占用的一些。


ps
我现在还都不是很理解这句话,所以本人不筹划用它。但不筹划用不意味着不能。
扫地以尽的方法: 手动纠正paddingTop的值+先了解Material
design5.0性子中文超详细总结关于如
顶上部分情状栏中度:24dp Appbar最小高度:56dp 尾部导航栏高度:48dp…


        <android.support.v7.widget.Toolbar
            xmlns:android="http://schemas.android.com/apk/res/android"
            app:layout_scrollFlags="scroll|enterAlways"
            android:id="@+id/toolbar"
            android:paddingTop="25dp"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@color/toolbar_background"
            app:popupTheme="@style/AppTheme.PopupOverlay"
            android:titleTextAppearance="@style/Theme.ToolBar.Title"/>
   <!--  android:fitsSystemWindows="true"-->

**显明提示:

android:fitsSystemWindows=”true” 不是特别领悟其规律,不要乱用。

代表情势:

手动更改 paddingTop 属性值

总结

学习三个新的学问必要变成以下几点

  • 寻找代码中不领悟的每一行代码-罗列成表
  • 各种找材质消除。推荐首先去掘金里面找绝对经刷选后的干货->google去找自备梯子(不要用百毒了)
  • 最终推荐多少个相比好的网站
    1.stackoverflow
    2.android
    API
    3.google
    翻译

发表评论

电子邮件地址不会被公开。 必填项已用*标注