android:Toolbar用法探析:内容显示微调

Posted FightSeeker

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了android:Toolbar用法探析:内容显示微调相关的知识,希望对你有一定的参考价值。

原生的Toolbar基本的功能样式已经在上节简单的说了一下,但是当前的样式并不满足我们的需要,因此这一节主要探索一下Toolbar的一些内容上调整的方法,比如Title位置居中的改变啊,PopuMenu菜单的显示位置等。

一:Toolbar的标题Title文字居中调整

关于Toolbar标题文字居中的写法,网上都是前篇一律的把Toolbar标题内容置为空,然后在里面添加一个TextView来实现的,代码如下:

<android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="?attr/colorPrimary"
        app:popupTheme="@style/AppTheme.PopupOverlay">
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:textSize="20sp"
                android:text="标题"/>
    </android.support.v7.widget.Toolbar>

这样虽然是实现了居中的效果,但是Toolbar的用法可不是这样的。下面,介绍另外一种标题居中的方法。先上效果图:

从效果图上看得出,文字已经居中显示了,那下面就是方法代码了:

    private void setTitleCenter(Toolbar toolbar)
        int childCount = toolbar.getChildCount();
        for(int i = 0 ;i < childCount;i++)
            View child = toolbar.getChildAt(i);
            if(child instanceof TextView)
                TextView childTitle = (TextView)child;
                if(childTitle.getText().equals(toolbar.getTitle()))
                    int deviceWidth = getWindowManager().getDefaultDisplay().getWidth();
                    Paint p = childTitle.getPaint();
                    float textWidth = p.measureText(childTitle.getText().toString());
                    float tx = (deviceWidth - textWidth) / 2.0f - toolbar.getContentInsetLeft();
                    childTitle.setTranslationX(tx);
                    break;
                
            
        
    

基本的思想是这样的:首先获取Toobar的子view 的个数,然后循环获取子view,因为用来显示title的是一个TextView的控件,所以需要判断当前view 是否是TextView,由于Toolbar中还包含一个副标题,所以这里判断TextView的内容是否是一样的(注意:这里副标题和标题之间的文字不能相同暂时),这个时候如果判断通过则进入if语句中。首先获取屏幕的宽度,然后在获取文字的宽度,最后计算出title控件需要移动的距离,然后调用setTranslationX即可。

二:Toolbar中的PopuMenu菜单的显示位置

自定义溢出菜单之前,首先需要说明一点的是,当前的Activity的主题样式需要设置为”Theme.AppCompat.Light.NoActionBar”(或者”Theme.AppCompat.NoActionBar”),以及parent为它的也可以。如下代码:

    <style name="AppTheme.NoActionBar" parent="Theme.AppCompat.Light.NoActionBar">
        <!--修改Toolbar背景色-->
        <item name="colorPrimary">@color/accent_material_dark</item>
        <!--修改状态栏底色-->
        <item name="colorPrimaryDark">@color/accent_material_light</item>
        <!--修改虚拟按键导航栏背景色,只能在API v21 也就是 Android 5 以后的版本中使用,
        因此要将之设定在 res/values-v21/styles.xml 里面才会起作用-->
        <item name="android:navigationBarColor">@color/accent_material_light</item>
    </style>

给Activity设置单独的主题样式:

        <activity
            android:name=".MainActivity"
            android:label="@string/app_name"
            android:logo="@mipmap/ic_launcher"
            android:theme="@style/AppTheme.NoActionBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

然后,自定义PopouMenu的溢出样式如下:

    <style name="OverflowMenuStyle" parent="@style/ThemeOverlay.AppCompat">
        <!-- 是否覆盖overflow按钮,默认为true,即盖住Toolbar -->
        <item name="overlapAnchor">false</item>
    </style>

最后给Toolebar设置poputheme,如下:

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbarMain"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="?attr/colorPrimary"
        app:popupTheme="@style/OverflowMenuStyle"
        />

这个时候效果图如下:

三:Toolbar内容调整

1.修改标题(“设置”)文字的颜色,在主题AppTheme.NoActionBar中添加如下代码即可。

        <!--Toolbar标题颜色修改-->
        <item name="android:textColorPrimary">@android:color/holo_blue_bright</item>

效果图:

从图上看出,修改的颜色不单单是标题的颜色,连点击overflowButton之后的PopuMenu弹框中的颜色也一起修改了。说明设置了这个属性之后这两个部分的文字颜色是一样的。

2.修改菜单栏MenuItem文字的颜色,即图中的”SETTINGS”文字

定义Toolbar菜单栏menu文字的样式如下:

    <!--Toolbar中menu文字样式-->
    <style name="ActionMenuTextStyle" parent="@style/ThemeOverlay.AppCompat.ActionBar">
        <item name="actionMenuTextColor">@android:color/white</item>
    </style>

定义好样式之后,设置app:theme=”@style/ActionMenuTextStyle”给Toolbar即可。如下代码:

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbarMain"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="?attr/colorPrimary"
        app:popupTheme="@style/OverflowMenuStyle"
        app:theme="@style/ActionMenuTextColor"
        />

然后看下效果图:

从图上看出,标题栏一行里面的“SETTINGS”文字颜色改为白色了额。

3.修改标题(“设置”)文字大小

颜色修改完了,现在看一下文字大小的修改。现在感觉文字有点小了,那好现在修改大一点的。现定义标题的样式如下:

    <!--Toolbar标题样式-->
    <style name="ToolbarTitle" parent="@style/TextAppearance.Widget.AppCompat.Toolbar.Title">
        <item name="android:textSize">35sp</item>
    </style>

然后设置此样式给Toolbar:app:titleTextAppearance=”@style/ToolbarTitle”,代码如下:

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbarMain"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="?attr/colorPrimary"
        app:popupTheme="@style/OverflowMenuStyle"
        app:theme="@style/ActionMenuTextStyle"
        app:titleTextAppearance="@style/ToolbarTitle"/>

效果图看下:

文字大小变大了,比以前大多咧。

4.修改Overflow中,PopuMenu中文字大小

上面已经定义了一个OverflowMenuStyle样式的PopuMenu,所以只需要在添加一项即可。代码如下:

    <style name="OverflowMenuStyle" parent="@style/ThemeOverlay.AppCompat">
        <!-- 是否覆盖锚点,默认为true,即盖住Toolbar -->
        <item name="overlapAnchor">false</item>
        <item name="android:textSize">30sp</item>
    </style>

由于前面已经给Toolbar设置了popuTheme样式,下面直接看效果图:

效果已经很明显了,文字被放大了。

5.单独给文字标题和Menu设置样式

从3和4中可以看出,只要设置不同的style就可以实现单独的样式设置。先改变如下:

    <!--Toolbar中MenuItem文字样式-->
    <style name="ActionMenuTextStyle" parent="@style/ThemeOverlay.AppCompat.ActionBar">
        <item name="actionMenuTextColor">@android:color/white</item>
        <item name="android:textSize">13sp</item>
    </style>

    <!--Toolbar标题样式-->
    <style name="ToolbarTitle" parent="@style/TextAppearance.Widget.AppCompat.Toolbar.Title">
        <item name="android:textSize">35sp</item>
        <item name="android:textColor">@android:color/white</item>
    </style>

    <!--PopuMenu样式-->
    <style name="OverflowMenuStyle" parent="@style/ThemeOverlay.AppCompat">
        <!-- 是否覆盖锚点,默认为true,即盖住Toolbar -->
        <item name="overlapAnchor">false</item>
        <item name="android:textSize">30sp</item>
        <item name="android:textColor">@android:color/holo_red_dark</item>
        <item name="android:colorBackground">#5a5a5a</item>
    </style>

样式改变如下:Toolbar标题栏中menu菜单的文字缩小,标题文字颜色变为白色,PopuMenu中文字变为红色,以及背景颜色现效果图如下:

6.修改PopuMenu中ListView的样式

发现PopuMenu中每一个MenuItem之间没有分割线,不爽!那么就自己定义一个样式,给它加上分割线,代码如下:

    <!-- PopuMenu ListView Styles -->
    <style name="PopupMenuListView" parent="@style/Widget.AppCompat.Light.ListView.DropDown">
        <item name="android:divider">@android:color/white</item>
        <item name="android:dividerHeight">1dp</item>
    </style>

然后在“AppTheme.NoActionBar”Activity主题样式中添加如下代码:

 <item name="android:dropDownListViewStyle">@style/PopupMenuListView</item>

效果图看下:

7.修改Menu的点击状态

有些时候吧,产品设计死脑筋,非得变一下点击的效果,所以这个时候原生的效果就不符合设计要求了,需要修改。那怎么改呢,先别急,先定义一个selector,如下:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@color/colorPrimaryDark" android:state_pressed="true" />
    <item android:drawable="@color/colorPrimaryDark" android:state_focused="true"/>
    <item android:drawable="@android:color/transparent"/>
</selector>

首先修改Toolbar中菜单栏MenuItem的点击效果,你只需要在“ActionMenuTextStyle”样式添加如下代码即可:

<item name="android:actionBarItemBackground">@drawable/menu_selector</item>

现看一下效果图:

从gif动画中看出,”SETTINGS”以及“OverflowButton”在点击的时候,会变为蓝色,而PopuMenu点击的时候颜色还是和以前的一样,没有修改。

那现在修改一下PopuMenu中Item点击的效果。你需要在“OverflowMenuStyle”样式中添加如下代码:

<item name="android:selectableItemBackground">@drawable/menu_selector</item>

现在再来看一下效果图:

加上如上代码之后,PopuMenu中item点击的效果也变了,如图所示。

8.给MenuItem设置icon

有些时候,menuItem中显示一下icon图标也是极好赏心悦目的。现改变menu布局如下:

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context="com.lingyun.toolbardemo.MainActivity">
    <item
        android:id="@+id/action_settings"
        android:orderInCategory="100"
        android:title="@string/action_settings"
        app:showAsAction="always"
        android:icon="@mipmap/ic_launcher"/>
    <item
        android:id="@+id/action_1"
        android:orderInCategory="100"
        android:title="@string/action_settings"
        app:showAsAction="never"
        android:icon="@mipmap/ic_launcher"/>
    <item
        android:id="@+id/action_2"
        android:orderInCategory="100"
        android:title="@string/action_settings"
        app:showAsAction="never"
        android:icon="@mipmap/ic_launcher"/>
</menu>

那么效果图来看下:

图上显示,Toolbar菜单栏中的MenuItem已经被icon图标替换,但是店址overflow之后的PopuMenu中并没有显示icon图标,怎么回事呢?这是官方的做法,默认只能显示文字而不能显示icon,但是觉得这样不美观啊,icon必须得显示出来。icon显示不显示是由MenuBuilder这个类的setOptionalIconsVisible方法来决定的,如果我们在PopuMenu被展开的时候给这个方法传入true,那么里面的每一个MenuItem对应的图标就都会显示出来了这个方法并没有对完开发,所以要调用此方法当然用到反射了。
(1)有的人可能把反射的代码卸载了onMenuOpened中,但是仍然可能是有问题的

    @Override
    public boolean onMenuOpened(int featureId, Menu menu) 
        if (featureId == Window.FEATURE_ACTION_BAR && menu != null) 
            if (menu.getClass().getSimpleName().equals("MenuBuilder")) 
                try 
                    Method m = menu.getClass().getDeclaredMethod("setOptionalIconsVisible", Boolean.TYPE);
                    m.setAccessible(true);
                    m.invoke(menu, true);
                 catch (Exception e) 
                
            
        
        return super.onMenuOpened(featureId, menu);
    

像我activity继承的是AppCompatActivity,所以,此方法行不通,在这就不贴图了。那把反射的地方换一下,通过重写onPrepareOptionsPanel方法来实现。

    @Override
    protected boolean onPrepareOptionsPanel(View view, Menu menu) 
        if (menu != null) 
            if (menu.getClass() == MenuBuilder.class) 
                try 
                    Method m = menu.getClass().getDeclaredMethod("setOptionalIconsVisible", Boolean.TYPE);
                    m.setAccessible(true);
                    m.invoke(menu, true);
                 catch (Exception e) 
                    e.printStackTrace();
                
            
        
        return super.onPrepareOptionsPanel(view, menu);
    

看下效果图如下:

9.修改navigation icon的padding值

修改padding值,就需要在style.xml中修改;在此我们修改的是navigation的pading值:

(1)定义style

 <style name="myToolbarNavigationButtonStyle" parent="@style/Widget.AppCompat.Toolbar.Button.Navigation">
        <item name="android:minWidth">0dp</item>
        <item name="android:padding">8dp</item>
        <item name="android:scaleType">centerInside</item>
    </style>

然后在“AppTheme.NoActionBar”Activity主题样式中添加如下代码:

<item name="toolbarNavigationButtonStyle">@style/myToolbarNavigationButtonStyle</item>

效果图就不贴了。

好了,到这里基本上的样式改变应该差不多都涉及到了。通过上面的探索,发现,针对不同的控件,会有单独的style样式供其设置来改变,就像ActionMenuTextStyle、ToolbarTitle、OverflowMenuStyle等,来改变相对应的控件的样式,剩下的得自己在探索了。

android:Toolbar用法探析(一):
http://blog.csdn.net/tabolt/article/details/51831930

以上是关于android:Toolbar用法探析:内容显示微调的主要内容,如果未能解决你的问题,请参考以下文章

android流式布局:FlexboxLayout用法探析

android特性之CoordinatorLayout用法探析实例

android流式布局:FlexboxLayout用法探析

Android 解决toolbar标题不显示问题

更高级的ToolBar使用----AppBarLayout

Python 中弱引用的神奇用法与原理探析