Android Toolbar使用详解

一,简介

Toolbar 是 android 5.0 引入的一个新控件,Toolbar出现之前,我们很多时候都是使用ActionBar以及ActionActivity实现顶部导航栏的,因此Toolbar可以理解为是ActionBar的升级版。Toolbar大大扩展了ActionBar,使用更灵活,不像ActionBar那么固定,Toolbar更像是一般的View元素,可以被放置在view树体系的任意位置,可以应用动画,可以跟着scrollView滚动,可以与布局中的其他view交互。

二,基本使用

Toolbar是Android 5.0推出的,所以为了实现向下兼容,可以使用兼容包appcompat-v7里的Toolbar。

1,引入v7支持库

implementation 'com.android.support:appcompat-v7:28.0.0-alpha3' 

2,编写布局文件

  • 编写主要布局activity_main.xml
    这里只列出一些常用的属性,比如最小高度,返回按钮的图标,背景,title等等。
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    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"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="?attr/colorPrimary"
        android:minHeight="?actionBarSize"
        app:navigationIcon="@drawable/af7"
        app:title="@string/home"/>

</android.support.constraint.ConstraintLayout>
  • 编写menu布局menu_toolbar.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/menu_search"
        android:icon="@drawable/search"
        android:title="@string/menu_search"
        app:showAsAction="ifRoom"/>
    <item
        android:id="@+id/menu_notification"
        android:icon="@drawable/message"
        android:title="@string/menu_notification"
        app:showAsAction="ifRoom"/>
    <item
        android:id="@+id/menu_close"
        android:title="@string/menu_setting"
        app:showAsAction="never"/>
    <item
        android:id="@+id/menu_about"
        android:title="@string/menu_about"
        app:showAsAction="never"/>
</menu>

3,设置style

通过设置style,使用亮色调的没有ActionBar的主题,注意需要在清单文件当中去使用自己定义的主题。为了完全去掉ActionBar,需要设置windowActionBar、windowNoTitle以及android声明的,确保把系统自带的以及第三方兼容包的ActionBar都彻底去掉。

<resources>
    <!-- Base application theme. -->
    <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="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
        <item name="android:windowActionBar">false</item>
        <item name="android:windowNoTitle">true</item>
    </style>

</resources>

4,代码中操作Toolbar

代码中能够设置Toolbar的一些列属性,如NavigationIcon,Logo,Title,subTitle,Menu等。

public class MainActivity extends AppCompatActivity {

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

    private void initToolbar() {
        Toolbar toolbar = findViewById(R.id.toolbar);

        //设置NavigationIcon
        toolbar.setNavigationIcon(R.drawable.menu_white);

        //设置Logo
        toolbar.setLogo(R.drawable.android);

        //设置主标题Title
        toolbar.setTitle("Title");
        toolbar.setTitleTextColor(Color.WHITE);

        //设置主标题文本的字体,大小,颜色等主题属性
        //toolbar.setTitleTextAppearance(getApplicationContext(), R.style.Theme_Toolbar_Base_Title);

        //设置Subtitle
        toolbar.setSubtitle("Subtitle");
        toolbar.setSubtitleTextColor(Color.WHITE);

        //设置子标题Subtitle文本的字体,大小,颜色等主题属性
        //toolbar.setSubtitleTextAppearance(getApplicationContext(), R.style.Theme_Toolbar_Base_Subtitle);

        //...

        //设置menu
        toolbar.inflateMenu(R.menu.menu_toolbar);

        //设置NavigationIcon点击响应
        toolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Toast.makeText(MainActivity.this, "Navigation", Toast.LENGTH_SHORT).show();
            }
        });

        //设置menu点击监听
        toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
            @Override
            public boolean onMenuItemClick(MenuItem menuItem) {
                int id = menuItem.getItemId();
                switch (id) {
                    case R.id.menu_search:
                        Toast.makeText(MainActivity.this, "search", Toast.LENGTH_SHORT).show();
                        break;
                    case R.id.menu_notification:
                        Toast.makeText(MainActivity.this, "notification", Toast.LENGTH_SHORT).show();
                        break;
                    case R.id.menu_setting:
                        Toast.makeText(MainActivity.this, "setting", Toast.LENGTH_SHORT).show();
                        break;
                    case R.id.menu_about:
                        Toast.makeText(MainActivity.this, "about", Toast.LENGTH_SHORT).show();
                        break;

                }
                return false;
            }
        });

}

注意:
1.在使用Toolbar之前一定要去掉系统自带的ActionBar,可以给Activity使用NoActionBar主题,或者在setContentView()之前调用supportRequestWindowFeature(Window.FEATURE_NO_TITLE)(或者是requestWindowFeature(Window.FEATURE_NO_TITLE))。
2.setTitleTextColor、setTitleTextAppearance、setSubtitleTextColor、setSubtitleTextAppearance可以在代码中修改相应的文本字体大小和颜色。

下面是效果图:


TIM截图.png

三,style中的颜色讲解

  • colorPrimaryDark是我们手机最顶端的状态栏的背景颜色(改变它需要Android5.0以及以上的手机支持才行)。
  • colorPrimary是指导航栏的颜色。
  • colorAccent是指我们常用控件比如Button等的颜色。
  • textColorPrimary是指我们导航栏中标题的颜色。
  • windowBackground是指我们窗体的默认颜色。
  • navigationBarColor是指Android手机中虚拟按键的背景颜色。


    image.png

四,自定义Toolbar

主要分为以下步骤

  • 自定义布局
  • 自定义属性
  • 自定义Toolbar
  • 使用自定义Toolbar

1,自定义布局

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

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:layout_marginRight="10dp">

        <ImageView
            android:id="@+id/toolbar_leftButton"
            android:layout_width="36dp"
            android:layout_height="36dp"
            android:layout_alignParentLeft="true"
            android:layout_centerVertical="true"
            android:src="@drawable/back"
            android:textColor="@android:color/white"
            android:visibility="visible"
            />

        <ImageView
            android:id="@+id/toolbar_rightButton"
            android:layout_width="36dp"
            android:layout_height="36dp"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            android:src="@drawable/more"
            android:textColor="@android:color/white"
            android:visibility="visible"
            />

        <TextView
            android:id="@+id/toolbar_title"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:layout_gravity="center"
            android:layout_marginLeft="10dp"
            android:layout_marginRight="10dp"
            android:layout_toLeftOf="@id/toolbar_rightButton"
            android:layout_toRightOf="@id/toolbar_leftButton"
            android:gravity="center"
            android:textColor="@android:color/white"
            android:textSize="20sp"
            android:visibility="visible"
            />

    </RelativeLayout>

</RelativeLayout>

这个自定义布局中,左右分别是一个ImageView,中间一个显示标题的TextView。这个布局很简单,由于一般不推荐把宽高以外的属性写在最外面根节点,因此我在最外面的相对布局里面又内嵌了一个相对布局,并且设置了左右的边距(margin)。

2,自定义属性

在values文件夹新建attrs.mxl文件,用于存放自定义的一些属性。

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="CustomToolbar">
        <attr name="leftButtonIcon" format="reference"/>
        <attr name="rightButtonIcon" format="reference"/>
        <attr name="myTitle" format="string"/>
    </declare-styleable>
</resources>

3,自定义Toolbar

public class CustomToolbar extends Toolbar {

    private TextView toolbar_title;
    private ImageView toolbar_leftButton;
    private ImageView toolbar_rightButton;
    private View mChildView;
    private Drawable left_button_icon;
    private Drawable right_button_icon;
    private String title;


    public interface OnLeftButtonClickListener {
        void onClick();
    }

    public interface OnRightButtonClickListener {
        void onClick();

    }

    private OnLeftButtonClickListener onLeftButtonClickListener;
    private OnRightButtonClickListener onRightButtonClickListener;

    public void setOnLeftButtonClickListener(OnLeftButtonClickListener listener) {
        onLeftButtonClickListener = listener;
    }

    public void setOnRightButtonClickListener(OnRightButtonClickListener listener) {
        onRightButtonClickListener = listener;
    }

    public CustomToolbar(Context context) {
        this(context, null, 0);
    }

    public CustomToolbar(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public CustomToolbar(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        //获取自定义属性
        final TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.CustomToolbar, defStyleAttr, 0);
        left_button_icon = a.getDrawable(R.styleable.CustomToolbar_leftButtonIcon);
        right_button_icon = a.getDrawable(R.styleable.CustomToolbar_rightButtonIcon);
        title = a.getString(R.styleable.CustomToolbar_myTitle);
        a.recycle();
        initView();//初始化视图
        initListener();//初始化监听器
    }

    private void initListener() {
        toolbar_leftButton.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {
                onLeftButtonClickListener.onClick();
            }
        });

        toolbar_rightButton.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {
                onRightButtonClickListener.onClick();
            }
        });
    }

    private void initView() {
        if (mChildView == null) {
            mChildView = View.inflate(getContext(), R.layout.custom_toolbar, null);
            toolbar_leftButton = mChildView.findViewById(R.id.toolbar_leftButton);
            toolbar_rightButton = mChildView.findViewById(R.id.toolbar_rightButton);
            toolbar_title = mChildView.findViewById(R.id.toolbar_title);
            addView(mChildView);
            if (left_button_icon != null) {
                toolbar_leftButton.setImageDrawable(left_button_icon);
            }
            if (right_button_icon != null) {
                toolbar_rightButton.setImageDrawable(right_button_icon);
            }
            if(toolbar_title != null) {
                toolbar_title.setText(title);
            }
        }
    }

    public void setMyTitle(String title){
        toolbar_title.setText(title);
    }

    public void setMyTitle(int resId){
        toolbar_title.setText(resId);
    }

    /**
     * 设置左右按钮的图标
     *
     * @param d
     */
    public void setLeftButtonIconDrawable(Drawable d) {
        toolbar_leftButton.setImageDrawable(d);
    }

    public void setRightButtonIconDrawable(Drawable d) {
        toolbar_rightButton.setImageDrawable(d);
    }

}

4,使用自定义Toolbar

  • 编写布局文件activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <com.wuping.toolbar.CustomToolbar
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="?attr/colorPrimary"
        android:minHeight="?attr/actionBarSize"
        app:leftButtonIcon="@drawable/back"
        app:rightButtonIcon="@drawable/more"
        app:myTitle="@string/home"/>

</RelativeLayout>
  • 代码中使用自定义Toolbar
public class MainActivity extends AppCompatActivity {

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

    private void init() {
        CustomToolbar customToolbar = findViewById(R.id.customToolBar);

        //由于自定义属性的值在布局中设置过了,代码可以不用设置了
        //设置左边图标
        //customToolbar.setLeftButtonIconDrawable(ContextCompat.getDrawable(this, R.drawable.back));

        //设置右边图标
        //customToolbar.setRightButtonIconDrawable(ContextCompat.getDrawable(this, R.drawable.more));

        //设置标题
        //customToolbar.setMyTitle("首页");

        //设置监听器
        customToolbar.setOnLeftButtonClickListener(new CustomToolbar.OnLeftButtonClickListener() {
            @Override
            public void onClick() {
                Toast.makeText(MainActivity.this, "返回", Toast.LENGTH_SHORT).show();
            }
        });

        customToolbar.setOnRightButtonClickListener(new CustomToolbar.OnRightButtonClickListener() {
            @Override
            public void onClick() {
                Toast.makeText(MainActivity.this, "更多", Toast.LENGTH_SHORT).show();
            }
        });
    }
}

效果图如下:


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