MeterialDesign系列文章(一)ToolBar的使用

因为最近在写一个表情包的项目,刚开始写UI的时候就把每个页面的头部都用了toolbar,原因就是我想主题颜色都是一种的,用ToolBar更方便,但是呢,看了一个大佬的代码后发现自己的想法真的是太。。。 然后自己又去网上找了好多优秀的项目,看了看别人的使用,下面就一步步说toolbar。

ToolBar的进阶历程

  • Toolbar的基本使用
  • Toolbar的进阶使用
  • 项目中的Toolbar

Toolbar的基本使用

首先我们要将ActionBar隐藏。像下面这样

  • 隐藏ActionBar
  <style name="AppTheme.NoActionBar" parent="Theme.AppCompat.Light.NoActionBar">
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
  </style>
复制代码

或者

 <style name="NoActionBar" parent="AppTheme">
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
 </style>
复制代码

主题的样式就可以通过colorPrimary、colorPrimaryDark、colorAccent来修改。

  • 设置ToolBar
<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"
    android:fitsSystemWindows="true"
    tools:context=".MainActivity">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="@color/dodgerblue"
        app:navigationIcon="@mipmap/back"
        app:titleTextColor="@color/colorWhite"
        app:title="知乎">
    </android.support.v7.widget.Toolbar>
复制代码

toobar展示

toolbar有些常用的属性介绍一下:

  • android:background 设置背景颜色
  • app:navigationIcon 上图返回图标的设置
  • app:title 设置显示的标题
  • app:titleTextColor 设置标题的颜色
  • app:subtitle 设置副标题
  • app:subtitleTextColor 设置副标题颜色
  • app:logo 设置Logo(返回图标和标题之前还有个logo)

Toolbar的进阶使用

有关导包

在初始化Toolbar的时候一般有两个

Toolbar(android.support.v7.widget)
Toolbar(android.widget)
复制代码

这里需要导入V7的包!!!否则,可能会找不到Toolbar这个类。

  • Toolbar标题的居中

如果在toolbar里加入TextView的话想让标题居中,就需要设置layout_gravity="center",若是想靠左就layout_gravity="left",靠右就layout_gravity="right"

<android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="@color/dodgerblue"
        app:navigationIcon="@mipmap/back"
        app:titleTextColor="@color/colorWhite"
        app:title="知乎">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:text="toolbar"
            android:textColor="@color/colorWhite"
            android:textSize="22sp"/>
</android.support.v7.widget.Toolbar>
复制代码

因为Toolbar是一个继承ViewGroup的控件,这就说明它是可以有内部控件的!

menu的设置

设置menu其实很简单,在bottomnavigationview(底部导航栏)的使用时也设置了相应的menu。Toolbar集成menu需要重写Activity的 boolean onCreateOptionsMenu(Menu menu) 方法,此方法返回一个boolean,用来判断你是否创建了相应的nenu文件。

  public boolean onCreateOptionsMenu(Menu menu){
        MenuInflater menuInflater = getMenuInflater();
        menuInflater.inflate(R.menu.toolbar_menu,menu);
        return true;
    }
复制代码

menu文件

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <item
        android:id="@+id/app_bar_search"
        android:title="搜索"
        app:actionViewClass="android.widget.SearchView"
        app:showAsAction="ifRoom" />
    <item
        android:id="@+id/menu_cycling"
        android:icon="@drawable/find"
        android:title="扫一扫"
        app:showAsAction="never" />
    <item
        android:id="@+id/collection"
        android:title="我的收藏"
        app:showAsAction="never" />
</menu>
复制代码

其中showAsAction可接受的值有: 这个属性可接受的值有:

  1. always:使菜单项一直显示在ToolBar上。
  2. ifRoom:如果有足够的空间,这个值会使菜单项显示在ToolBar上。
  3. never:使菜单项永远都不出现在ToolBar上,在…的子项中显示。
  4. withText:使菜单项和它的图标,菜单文本一起显示

现在menu并没有显示出来,因为不设置Actionbar是没有办法关联menu文件的。所以

public void setToolBar(){
        toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
}

  public boolean onCreateOptionsMenu(Menu menu){
        MenuInflater menuInflater = getMenuInflater();
        menuInflater.inflate(R.menu.toolbar_menu,menu);
        return true;
}
复制代码

setSupportActionbar(toolbar) 这一行代码千万不能忘,否则menu是显示不出来的!!!

我们现在发现...和搜素的图标都是黑色的和白色的字体很很不搭,而且点开...是这样的。。。

修改menu弹出的位置和样式

Toolbar有一个属性 popuptheme="@style/ToolbarPopupTheme" 这个属性是给Toolbar设置主题的!

  • 修改弹出框的文字样式、popup背景的样式
<style name="ToolbarTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <item name="android:background">#ffffff</item><!--设置弹框背景颜色-->
        <item name="android:textColorPrimary">#000000</item><!--设置文字颜色-->
        <item name="android:textSize">16sp</item><!--设置文字大小-->
    </style>
复制代码
  • 修改弹出框的位置问题
<style name="ToolbarTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="android:background">#ffffff</item>
    <item name="android:textColorPrimary">#000000</item>
    <item name="android:textSize">16sp</item>
    <item name="actionOverflowMenuStyle">@style/OverflowMenuTheme</item>
</style>

<style name="OverflowMenuTheme" parent="Widget.AppCompat.PopupMenu.Overflow">
    <item name="overlapAnchor">false</item>><!--这个属性设置为false,就能使得popup在Toolbar的下面显示-->
</style>
复制代码

位置文字颜色设置了,但是溢出菜单和搜索那个按钮太丑了

  • 修改溢出菜单的颜色

修改溢出菜单就是要修改相应的主题样式,就是在文章开始修改的主题,只要在上面加上 item name="android:textColorSecondary"... 就可以了。

<!-- Base application theme. -->
<style name="AppTheme.NoActionBar" 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="android:textColorSecondary">#ffffff</item>
</style>
复制代码

一些相应的监听

设置监听分为两种 1.设置ActionBar的监听(针对menu的开发内容)2.针对Toolbar内部设置的控件和navigationIcon的监听

  • menu的监听

对于menu的监听 onOptionItemSelected(MenuItem item) 这个方法,和onClickListener的监听都类似

public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case R.id.menu_find:
            Toast.makeText(this, "扫一扫", Toast.LENGTH_SHORT).show();
            break;
        case R.id.menu_colection:
            Toast.makeText(this, "收藏", Toast.LENGTH_SHORT).show();
            break;
        }
        return true;
    }
复制代码
  • 返回的监听

因为大部分的应用都会在此处处理返回的逻辑。google也早就设计好了,所以把navigationIcon的监听单独到Toolbar身上了

  public void setToolbarListener(){
       toolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });
    }
复制代码

项目中的Toolbar

我觉得一个项目成功的开始就在于UI,UI的美观真的很重要,而且还要考虑加载UI时间的问题(从自己做项目开始才开始考虑这些问题 笑哭==),之前一直让我很困扰的是项目里的头部(就是类似在toolbar的位置上的那些控件开始如何摆放的),最开始我是该每个控件加背景用相对布局,之后学会toolbar开始在toolbar里放控件,但是发现一个问题,toolbar里会被限制,有好多空间的位置不好确定,后来去看了别人的项目才发现toolbar一般都是被重写的,目的是为了重复利用,因为有好多的页面他们的toolbar的布局是一样的,只是控件的样式发生了改变,这里面标签就有了很大的用处。

上面说到了toolbar的重写,也就是自定义view,toolbar可以继承LinearLayout,也可以直接继承toolbar。下面是继承Linearlayout的一种写法,我在项目中学到的。

public class Toolbar extends LinearLayout implements View.OnClickListener {
    TextView title;
    ImageView back;
    public ImageView right1,right2;

    public Toolbar(Context context) {
        super(context);
        initViews();
    }

    public Toolbar(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        initViews();

    }

    public Toolbar(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initViews();

    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public Toolbar(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        initViews();
    }

    private void initViews() {
        View view = LayoutInflater.from(getContext()).inflate(R.layout.widget_toolbar, this, false);
        addView(view);
        title = findViewById(R.id.title);
        right1 = findViewById(R.id.right1);
        right2 = findViewById(R.id.right2);
        findViewById(R.id.back).setOnClickListener(this);
        if (((Activity) getContext()).getTitle() != null) {//判断该Activity标题是否为空,不为空设置到标题
            title.setText(((Activity) getContext()).getTitle());
        }
        setRightButtonOneShow(false);//按钮不可见(GONE)
        setRightButtonTwoShow(false);//按钮不可见(GONE)
    }

    //设置标题
    public void setTitle(String title) {
        this.title.setText(title);
    }

    //设置分享按钮是否显示
    private void setRightButtonOneShow(boolean visibility){
       int i = visibility? View.VISIBLE:View.GONE;
       right1.setVisibility(i);
    }
    private void setRightButtonTwoShow(boolean visibility){
       int i = visibility? View.VISIBLE:View.GONE;
       right2.setVisibility(i);
    }


    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.back:
                ((Activity) getContext()).finish();
                break;
        }
    }
}
复制代码

这里就是重写的代码,initViews()里初始化了布局中的控件,不想显示的可以隐藏,有兴趣的可以看看标签,用于隐藏某些控件。

下面是.xml文件

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="50dp"
    android:background="@color/colorPrimary"
    android:gravity="center_vertical"
    android:orientation="horizontal">

    <ImageView
        android:id="@+id/back"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:background="?attr/selectableItemBackground"
        android:padding="15dp"
        android:src="@drawable/back" />

    <TextView
        android:id="@+id/title"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:lines="1"
        android:text="标题"
        android:textColor="@color/colorBlack"
        android:textSize="20sp"
        android:textStyle="bold" />

    <ImageView
        android:id="@+id/right1"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:background="?attr/selectableItemBackground"
        android:padding="15dp"
        android:src="@drawable/share" />

    <ImageView
        android:id="@+id/right2"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:background="?attr/selectableItemBackground"
        android:padding="15dp"
        android:src="@drawable/share" />
</LinearLayout>
复制代码

加油哇!!!

猜你喜欢

转载自juejin.im/post/5c56524551882562d27419aa