Android--ToolBar基本介绍

1、简介

ToolBar 是 Android5.0 推出的导航控件,官方在某些程度上认为 ActionBar 限制了 android app 的开发与设计的弹性,所以 ToolBar 的出现可以说是用来代替 Action_Bar。的确对比 Action_Bar,ToolBar 的使用灵活的多,我们可以将我们想要的控件任意的添加在 ToolBar 里面,得到缤纷的效果。

2、使用前说明

1、兼容

官方考虑到仍有一部分用户的手机版本号低于5.0,所以,ToolBar 也放进了 support v7 包内,如果使用的是的 Android5.0 以下,那么可以在配置文件中引入它的包:

dependencies {    
      compile fileTree(dir: 'libs', include: ['*.jar'])    
      compile 'com.android.support:appcompat-v7:25.3.1'
}

不过如今的手机已经基本上都是 Android5.0 以上的了,我就不使用兼容包里的 ToolBar 了,其实使用方法都是差不多的。

2、去除ActionBar

因为新建工程都会默认使用有 ActionBar 的主题,但 ToolBar 是不能和 ActionBar 共用的,所以我们要想使用 ToolBar,就必须去掉 ActionBar:

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
style>

去掉 ActionBar 的方法很多,我们可以直接换一个没有 ActionBar 的样式,还可以在样式里添加 item,设置隐藏 ActionBar:

要注意的是,使用 API Level 22以上编译的话,要拿掉前綴字:

<item name="windowActionBar">falseitem>
<item name="windowNoTitle">trueitem>

要把 ActionBar 隐藏起来很简单的修改就可以做到啦。

3、简单使用ToolBar

我们的 ToolBar 是一个控件,所以我们对它的使用可以放在 xml 布局文件里:


<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Toolbar
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <TextView
            android:text="标题"
            android:textSize="20sp"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

    Toolbar>

RelativeLayout>

我们在内部放了一个 TextView,这是与 ActionBar 最大的不同,因为 ToolBar 实际上是一个 ViewGroup,支持在其内部放入子View。

Android--ToolBar基本介绍_第1张图片

我们给 ToolBar 加了个 TextView,虽然成功显示出来了,但可能会问这跟 TextView 有什么不一样,一点都没有导航栏的样子,不过这只是最简单的用法,它还有很多的功能和属性要介绍。

4、完善ToolBar

1、设置各种颜色

看上去与在界面上添加了一个 TextView 没什么两样,就是因为我们 ToolBar 的颜色与界面的背景色一样,这样就看不出在 TextView 外还有一个 ViewGroup,所以我们要想让它像是导航栏,首先来改变 ToolBar 的颜色。


    

我们要在 styles.xml 中给样式的属性赋值,然后在布局中把值赋给控件:


<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Toolbar
        android:background="?attr/colorPrimary"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <TextView
            android:text="标题"
            android:textSize="20sp"
            android:textColor="#FFFFFF"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    Toolbar>

RelativeLayout>
android:background="?attr/colorPrimary"

用这种引用方式就能把我们设置的颜色传给 ToolBar 了,其它的控件也能使用这个方式。

Android--ToolBar基本介绍_第2张图片

我们可以看到无论是 ToolBar 还是状态栏的颜色都被我们改变了,这就是我们设置的那几个颜色属性的功劳了。刚刚是直接就设置了,现在来说说它们各个的功能:

Android--ToolBar基本介绍_第3张图片

colorPrimaryDark:状态栏底色,在样式 (styles) 或是主题 (themes) 里进行设定。

App bar 底色:这个设定分为二部分,若我们仍是使用 ActionBar ,则直接在样式里设定 colorPrimary 参数即可;若是采用 toolbar 的话,则要在布局中设定 ToolBar 控件的 background 属性,就像上面一样。

navigationBarColor:导航栏底色。

windowBackground:主视窗底色。

colorAccent:对应EditText编辑时、RadioButton选中、CheckBox等选中时的颜色。

textColorPrimary:如果想要改变toolbar的title、subtitle以及menu中文字的颜色,可以利用这个属性,不过 ToolBar 要想用同样要在控件中设置属性

<item name="android:textColorPrimary">#FFFFFF

android:textColor="?android:attr/textColorPrimary"

2、设置ToolBar属性

ToolBar 有许多可以设置的属性,我们可以设置它的 title、subtitle、logo 还有导航栏图标等等,这既可以在 xml 中设置也可以用代码完成:


<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Toolbar
        android:title="Title"
        android:subtitle="SubTitle"
        android:navigationIcon="@mipmap/list"
        android:subtitleTextColor="?android:attr/textColorPrimary"
        android:logo="@mipmap/ic_launcher"
        android:background="?attr/colorPrimary"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <TextView
            android:text="标题"
            android:textSize="20sp"
            android:textColor="?android:attr/textColorPrimary"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

    Toolbar>

RelativeLayout>

Android--ToolBar基本介绍_第4张图片

可以看到我们用 ToolBar 给我们的组件添加了不少东西(如果是 support_v7,需要用 app 来引用属性),现在再用代码来实现一下:

public class MainActivity extends AppCompatActivity {

    private Toolbar mToolBar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mToolBar = (Toolbar) findViewById(R.id.id_toolbar);

        // 主标题,默认为app_label的值
        mToolBar.setTitle("Title");

        // 副标题
        mToolBar.setSubtitle("SubTitle");
        mToolBar.setSubtitleTextColor(Color.parseColor("#FFFFFF"));
        //App Logo
        mToolBar.setLogo(R.mipmap.ic_launcher);

        //侧边栏的按钮
        mToolBar.setNavigationIcon(R.mipmap.list);

        //取代原本的actionbar,设置导航图标要在setActionBar方法之后
        setActionBar(mToolBar);
    }
}

这里稍微提一下,我们这里使用的不是 support_v7 的 ToolBar,所以在导包的时候要注意,而且这里使用的是 setActionBar() 而不是 setSupportActionBar() 方法。

5、菜单项

用过 ActionBar 的朋友都知道,我们经常要 res/menu 目录下编写我们的导航栏选项,这无疑是导航栏中相当重要的部分,既然用 ToolBar 替代了 ActionBar,那当然就不得不提了。

首先我们还是要编写 menu_main.xml 文件,Android Studio 取消了默认生成 menu 文件夹,我们新建一个即可:

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" tools:context=".MainActivity">

    <item android:id="@+id/action_search"
        android:title="Search"
        android:icon="@mipmap/toolbar_search_icon"
        android:showAsAction="always"/>

    <item android:id="@+id/action_notifications"
        android:title="notifications"
        android:icon="@mipmap/toolbar_add_icon"
        android:showAsAction="always"/>
menu>

我们在 ToolBar 里增添两项,关于 showAsAction 的介绍我在博客Android控件–RecyclerView做过说明,有兴趣的朋友可以看看,在这里就不说明了。

这里用了这样一个属性 android:showAsAction=”always”,大家可能会看到 Android Studio 对这行报错,因为它不建议使用这个,但其实这个并不影响运行,之所以用这个是因为我们使用的不是 support v7 包的 ToolBar,所以不能用下面的方式:

xmlns:app="http://schemas.android.com/apk/res-auto"

app:showAsAction=""

app 是自定义的命名空间,它适用于 support v7 包,用这个我们加的这两个 item 就不会显示在 ToolBar 上,而是在溢出列表里,当然如果使用的是 support v7 下的 ToolBar,就要用这个啦。

然后自然就是要重写 onCreateOptionsMenu(),把设置好的菜单添加过去 :

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

Android--ToolBar基本介绍_第5张图片

因为我们用得是 always,如果是 always 或者是 ifroom,那么有三个黑点的 overflow 溢出列表就不会出现在 ToolBar 中,似乎默认就是出现两个 item,列表 item 就不会出现。我们把 add 的 item 设为 never。

6、点击事件

1、菜单点击事件

菜单有了,就要为 item 添加点击事件才能实现想要的功能,这样菜单才会有实际用途,添加点击事件也很方便:

mToolBar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
    @Override
    public boolean onMenuItemClick(MenuItem item) {

        switch (item.getItemId()) {
            case R.id.tool_search :
                Toast.makeText(MainActivity.this, "search click", Toast.LENGTH_SHORT).show();
                break;
            case R.id.tool_add :
                Toast.makeText(MainActivity.this, "add click", Toast.LENGTH_SHORT).show();
                break;
        }

        return true;
    }
});

Android--ToolBar基本介绍_第6张图片

2、图标点击

ToolBar 还有一个比较特殊的点击,那就是导航栏的图标的点击事件,我来介绍一下:

//设置NavigationIcon的点击事件,需要放在setActionBar()之后设置才会生效,
//因为setActionBar里面也会调用setNavigationOnClickListener,会覆盖我们设置的
mToolBar.setNavigationOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Toast.makeText(MainActivity.this, "click", Toast.LENGTH_SHORT).show();
    }
});

Android--ToolBar基本介绍_第7张图片

7、overflow图标

在上面我们知道溢出列表的图标的样式,有时候我们并不满意这个图标,就像微信一样它把 overflow 的图标变成了我们上面用过的“+”,所以我们来讲讲怎么变换 overflow 的图标。

overflow 是系统给我们的 item,所以我们要想修改那就要到 style.xml 文件中变更我们的样式:

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    。。。  
    <item  name="android:actionOverflowButtonStyle">@style/MyOverflowStyle  
style>  

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

我们将我们制定好的 overflow 的样式加入 APP 引用的样式里去,AppTheme 就是系统默认引用样式的名字。这里要使用的是 mipmap,因为这里引用图片不会做处理,而在 mipmap 里的图片会适应我们 Android 机的分辨率,大家可以引用 drawable 和 mipmap 里的图片做比较。

Android--ToolBar基本介绍_第8张图片

这样就设置了我们自己的图片为 overflow 的图标啦。

8、调整溢出列表

我们在上面实现了 overflow 的更换图标以及显示,但我们看到因为设置的字体是白色的,而背景色同样是白的,所以我们很难看清它显示的是什么,并且列表展开的位置也不是很好,我们应该让它显示在 ToolBar 下才好,所以现在就来改变这些属性。

1、改变背景色

这个背景色是系统给我们的,所以我们要改也可以在 style.xml 中重写它的样式:


<style name="ToolbarPopupTheme" parent="@style/ThemeOverlay.AppCompat.Dark">   
     <item name="android:colorBackground">#000000item>
style>

设置好样式后,在 ToolBar 里有个 popupTheme,就是给我们用来设置菜单的样式的:

android:popupTheme="@style/ToolbarPopupTheme"

Android--ToolBar基本介绍_第9张图片

2、改变字体大小与颜色

字体的大小颜色对于美观来说也是至关重要的,在很多时候就会用上:

<item name="android:textSize">18spitem>
<item name="android:textColor">#bcbcbc

直接在使用的 style 中加上对 Text 的属性修改即可。

Android--ToolBar基本介绍_第10张图片

3、移动列表位置

我们用 overlapAnchor 这个属性就可以修改它的位置,使它处于Toolbar之下,这样会变得更美观:

把它设为 false 意味着我们不要溢出列表覆盖我们的 ToolBar。

Android--ToolBar基本介绍_第11张图片

9、自定义overflow

在上面的说明中我们可以看到,系统提供给我们的 overflow 列表设定起来并不是特别容易,而且有时也无法满足我们的需求,这个时候我们可以舍弃系统的 overflow,自己自定义个弹出窗口,这就要用到 PopupWindow,它用来制作这种 layout 是很灵活的。

我们先来为 PopupWindow 写一个布局,action_toolbar_overflow.xml:


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="#1b1c1d"
    android:orientation="vertical"
    android:padding="10dp">

    <LinearLayout
        android:id="@+id/ll_item1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center">

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@mipmap/ic_launcher" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="10dp"
            android:text="item1"
            android:textColor="#ffffff"
            android:textSize="20sp" />
    LinearLayout>

    <LinearLayout
        android:id="@+id/ll_item2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center">

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@mipmap/ic_launcher" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="10dp"
            android:text="item2"
            android:textColor="#ffffff"
            android:textSize="20sp" />
    LinearLayout>

    <LinearLayout
        android:id="@+id/ll_item3"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center">

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@mipmap/ic_launcher" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="10dp"
            android:text="item3"
            android:textColor="#ffffff"
            android:textSize="20sp" />
    LinearLayout>
LinearLayout>

我们既然弃用了系统的,那我们应该再设置一个图标设置点击弹出窗口,就用之前的 add 的 item:

<item android:id="@+id/tool_overflow"
    android:icon="@mipmap/toolbar_add_icon"
    android:showAsAction="always"
    android:title="overflow" />

然后就用代码设置到我们的 Activity 里:

public class MainActivity extends AppCompatActivity implements View.OnClickListener{

    private Toolbar mToolBar;
    private PopupWindow mPopupWindow;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mToolBar = (Toolbar) findViewById(R.id.id_toolbar);

        setSupportActionBar(mToolBar);

        mToolBar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
            @Override
            public boolean onMenuItemClick(MenuItem item) {

                switch (item.getItemId()) {
                    case R.id.tool_search :
                        Toast.makeText(MainActivity.this, "search click", Toast.LENGTH_SHORT).show();
                        break;
                    case R.id.tool_overflow :
                        popUpMyOverflow();
                        break;
                }

                return true;
            }
        });
    }

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

    /**
     * 弹出自定义的popWindow
     */
    public void popUpMyOverflow() {
        //获取状态栏高度
        Rect frame = new Rect();
        getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
        //状态栏高度+toolbar的高度
        int yOffset = frame.top + mToolBar.getHeight();
        if (null == mPopupWindow) {
            //初始化PopupWindow的布局
            View popView = getLayoutInflater().inflate(R.layout.action_overflow_popwindow, null);
            //popView即popupWindow的布局,ture设置focusable.
            mPopupWindow = new PopupWindow(popView,
                    ViewGroup.LayoutParams.WRAP_CONTENT,
                    ViewGroup.LayoutParams.WRAP_CONTENT, true);
            //必须设置BackgroundDrawable后setOutsideTouchable(true)才会有效
            mPopupWindow.setBackgroundDrawable(new ColorDrawable());
            //点击外部关闭。
            mPopupWindow.setOutsideTouchable(true);
            //设置一个动画。
            mPopupWindow.setAnimationStyle(android.R.style.Animation_Dialog);
            //设置Gravity,让它显示在右上角。
            mPopupWindow.showAtLocation(mToolBar, Gravity.RIGHT | Gravity.TOP, 0, yOffset);
            //设置item的点击监听
            popView.findViewById(R.id.ll_item1).setOnClickListener(this);
            popView.findViewById(R.id.ll_item2).setOnClickListener(this);
            popView.findViewById(R.id.ll_item3).setOnClickListener(this);
        } else {
            mPopupWindow.showAtLocation(mToolBar, Gravity.RIGHT | Gravity.TOP, 0, yOffset);
        }

    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.ll_item1:
                Toast.makeText(this, "item1", Toast.LENGTH_SHORT).show();
                break;
            case R.id.ll_item2:
                Toast.makeText(this, "item2", Toast.LENGTH_SHORT).show();
                break;
            case R.id.ll_item3:
                Toast.makeText(this, "item3", Toast.LENGTH_SHORT).show();
                break;
        }
        //点击PopWindow的item后,关闭此PopWindow
        if (null != mPopupWindow && mPopupWindow.isShowing()) {
            mPopupWindow.dismiss();
        }
    }
}

里面大都是 PopUpWindow 的基本方法调用,有了注解知道方法的作用就知道为什么使用了,没什么好说明的,所以就直接看看效果吧:

Android--ToolBar基本介绍_第12张图片

可以看到它对比系统组件的灵活性,如果好好设计肯定会得到十分美观的效果。

10、ToolBar中的SearchView

大家肯定都用过微信,微信的搜索图标点击后会出现搜索栏:

Android--ToolBar基本介绍_第13张图片

现在我们就来看看怎么实现这个功能:

<item android:id="@+id/tool_search"
    android:actionViewClass="android.widget.SearchView"
    android:icon="@mipmap/toolbar_search_icon"
    android:showAsAction="ifRoom|collapseActionView"
    android:title="search" />

我们只要给它设置使用 SearchView,如果用得是 Support_v7 包下的 ToolBar,那就要用:

app:actionViewClass="android.support.v7.widget.SearchView"

showAsAction 也要设置为 ifRoom|collapseActionView,我们的 SearchView 才可以展开。

Android--ToolBar基本介绍_第14张图片

要想在 ToolBar 获得 SearchView 的实例,我们可以这样做:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.menu_main, menu);
    MenuItem item = menu.findItem(R.id.tool_search);
    SearchView mSearchView = (SearchView) MenuItemCompat.getActionView(item);

    mSearchView.setIconifiedByDefault(false);
    return true;
}

setIconifiedByDefault() 方法可以让我们在点击图标跳转到别的 Activity 时使用 SearchView 为展开状态。

点开 SearchView 的源码,我们可以找到搜索图标的 ID,如果你对图标不满意,可以进行修改:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.menu_main, menu);
    MenuItem item = menu.findItem(R.id.tool_search);
    SearchView mSearchView = (SearchView) MenuItemCompat.getActionView(item);

    int search_mag_icon_id = mSearchView.getContext().getResources().
            getIdentifier("android:id/search_mag_icon", null, null);

    // 获取搜索图标
    ImageView mSearchViewIcon = (ImageView) mSearchView.findViewById(search_mag_icon_id);

    mSearchViewIcon.setImageResource(R.mipmap.toolbar_search_icon);

    mSearchView.setIconifiedByDefault(false);
    return true;
}

是 Support_v7 包的用如下代码即可:

ImageView imageView = (ImageView) mSearchView.findViewById(R.id.search_mag_icon);
imageView.setImageResource(R.mipmap.toolbar_search_icon);

Android--ToolBar基本介绍_第15张图片

这个箭头的修改我并没找到方法,大家要注意的是,如果你的样式是 Light 的话,这两个系统的图标就会是黑色的,想要白色的图标,就要使用没有 light 的样式,如:

Theme.AppCompat.NoActionBar

不过这时候 WindowBackground 就变成黑色的了,我们还要在其中添加 item 进行修改:

<item name="android:windowBackground">@color/windowBackgrounditem>
<color name="windowBackground">#FFFFFF

所以说对于系统所给的样式的修改是比较让人烦恼的。

结束语:本文仅用来学习记录,参考查阅。

你可能感兴趣的:(android控件,android)