Toolbar和沉浸式基类的封装

2017-11-27  本文已影响91人  耳_总
Toolbar基本使用和主题

在AppCompat主题出来之后,基本上都是用这个主题,方便管理整个app的主题风格。

<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>
       
    </style>

colorPrimary一般是toolbar的颜色,colorPrimaryDark为statubar默认的颜色,注意:如果要使用toolbar作为导航栏的话,必须是NoActionBar的主题(也可以在Activity中用代码设置)。
建一个toolbar.xml:

<android.support.v7.widget.Toolbar
    xmlns:android="http://schemas.android.com/apk/res/android"
         android:layout_width="match_parent"
         android:id="@+id/toolbar"
         android:layout_height="?android:actionBarSize"
         android:background="@color/colorPrimary">
</android.support.v7.widget.Toolbar>

这里设置了toolbar最基本的属性,Toolbar是继承ViewGroup的,所以ViewGroup拥有的属性Toolbar一样也会有。?android:actionBarSize为设置高度,用系统默认的导航栏的高度,背景颜色用主题中设置的颜色。
以include方式引入,方便管理:

<LinearLayout
    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:orientation="vertical"
    tools:context="test.xc.com.toolbartest.MainActivity">

    <include layout="@layout/toobar"></include>

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

</LinearLayout>

toolbar本身就是一个View,只能每次嵌入布局中,但是为了统一,一般通过include方式引入。
在代码中引用:

setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);

通过setSupportActionBar(toolbar);toolbar就会拥有Actionbar的一些属性,可以通过ActionBar actionBar = getSupportActionBar();(注意这里是返回ActionBar )来操作toolbar。
运行效果是这样子的:


image.png

显然这不符合我们的要求,平时我们公司应用的开发头部有几种情况:左边有返回按钮,中间标题,字体白色,右边可能还有一个按钮,中间还有可能是搜索。面对这些情况,我们不可能不同的页面用不同的布局来表示,必须得要封装。下面就是改造的过程,一些基本的属性和不常用的就不讲了。

        setContentView(R.layout.activity_main);
        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        ActionBar actionBar = getSupportActionBar();
        //设置是否显示返回按钮,注意:这里个方法是actionBar的方法
        actionBar.setDisplayHomeAsUpEnabled(true);

        //设置返回键的监听
        toolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });
image.png

返回按钮在现在的版本中默认是不显示的,需要调用actionBar.setDisplayHomeAsUpEnabled(true);方法才能显示,通过setNavigationOnClickListener()来监听事件,一般返回按钮都是销毁Activity,
当然,如果我们有设计自己的返回按钮的话只需要调用toolbar.setNavigationIcon(),来进行自定义。对应的xml属性为:app:navigationIcon="@mipmap/ic_drawer_home"
如果想要用系统的返回键而,要改变颜色呢?这就需要通过toolbar的主题来设置了。

<android.support.v7.widget.Toolbar
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:toolbar="http://schemas.android.com/apk/res-auto"
    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="?android:actionBarSize"
    android:background="@color/colorPrimary"
    android:theme="@style/toolbar_blue_theme"
    toolbar:popupTheme="@style/ThemeOverlay.AppCompat.Light"
    toolbar:subtitle=""
    toolbar:title="">

    <TextView
        android:id="@+id/toolbar_center_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:textColor="#ffffff"
        android:textSize="18sp"
        />

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

需要给toolbar设置一个主题android:them,

<!-- ToolBar样式.-->
    <style name="toolbar_blue_theme" parent="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
        <!-- 改变返回键、标题、菜单栏颜色.-->
        <item name="colorControlNormal">@color/white</item>
    </style>

colorControlNormal是给toolbar的返回键等设置颜色。如果要设置其他属性必须要用toolbar的自定义属性,toolbar说白了就是一个自定义View,系统没有的属性就要用自定义属性。
此外,toolbar具有高度自定义特性,我们可以防止一个TextView放到toolbar中间作为中间标题栏。

<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_launcher"
        android:title="@string/app_name"
        app:showAsAction="ifRoom" />

    <item
        android:id="@+id/action_notification"
        android:icon="@mipmap/ic_launcher"
        android:title="@string/app_name"
        app:showAsAction="ifRoom" />

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

    <item
        android:id="@+id/actionresom2"
        android:title="@string/app_name"
        app:showAsAction="never" />
</menu>
//showAsAction这个属性的值有: 
//1、always:使菜单项一直显示在ToolBar上。 
//2、ifRoom:如果有足够的空间,这个值会使菜单项显示在ToolBar上。 
//3、never:使菜单项永远都不出现在ToolBar上,在…的子项中显示。 
//4、withText:使菜单项和它的图标,菜单文本一起显示。

代码中:
toolbar.inflateMenu(R.menu.toolbar_menu);
toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
            @Override
            public boolean onMenuItemClick(MenuItem item) {
//                item.getActionView();
//                item.getIcon();
                Toast.makeText(MainActivity.this,item.getTitle(),Toast.LENGTH_LONG).show();
                return false;
            }
        });

这里有个小小的坑如果按照如上代码写,是没有任何效果的,是因为setSupportActionBar(toolbar);这句话的原因注释掉菜单栏就全部出来了。

需要重写activity的方法:

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

另外 还有有关菜单弹出框的主题:

<!-- ToolBar菜单样式.-->
    <style name="popup_theme" parent="@style/ThemeOverlay.AppCompat.Dark">
        <item name="android:background">@android:color/white</item>
        <!--<item name="android:textColor">@android:color/holo_red_dark</item>-->
        <item name="actionOverflowMenuStyle">@style/OverflowMenuStyle</item>
    </style>
    <style name="OverflowMenuStyle" parent="Widget.AppCompat.Light.PopupMenu.Overflow">
        <!--设置不覆盖锚点-->
        <item name="overlapAnchor">false</item>
    </style>
public abstract class BaseToolbarActivity extends BaseActivity implements Toolbar.OnMenuItemClickListener {

    Toolbar mToolbar;
    TextView mTitleName;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if(getContentViewLayoutID() != 0){
            setContentView(getContentViewLayoutID());
            initToolbar();
        }
    }

    private void initToolbar() {
        mToolbar = findViewById(R.id.toolbar);
        mTitleName = findViewById(R.id.toolbar_center_title);
        if (mToolbar != null){
            mToolbar.setTitle("");
            mTitleName.setText(getSubTitle());
            setSupportActionBar(mToolbar);
            if (isShowBack()){
                showBack();
            }
            if(getMenu() != 0) {
                mToolbar.inflateMenu(getMenu());
            }
        }
    }

    /**
     * 版本号小于21的后退按钮图片
     */
    private void showBack(){
        //setNavigationIcon必须在setSupportActionBar(toolbar);方法后面加入
//        mToolbar.setNavigationIcon(R.mipmap.icon_back);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                onNavigationBtnClicked();
            }
        });
        mToolbar.setOnMenuItemClickListener(this);
    }

    /**
     * 右边菜单点击事件
     * @param item
     * @return
     */
    @Override
    public boolean onMenuItemClick(MenuItem item) {

        return false;
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        if(getMenu() != 0) {
            getMenuInflater().inflate(getMenu(), menu);
            return true;
        }
        return super.onCreateOptionsMenu(menu);
    }

    /**
     * 设置标题文本
     */
    public abstract String getSubTitle();

    /**
     * 右边导航菜单栏
     * @return
     */
    public int getMenu() {
        return 0;
    }

    public void onNavigationBtnClicked() {
        finish();
    }


    /**
     * 是否有返回按钮
     * @return
     */
    protected boolean isShowBack(){
        return true;
    }

}

一般有toolbar的activity还会继承一个基类,然后对toolbar进行封装,添加一些工厂方法让子类去选择实现。
参考:
http://www.jianshu.com/p/ae0013a4f71a
http://www.codeceo.com/article/android-toolbar-develop.html
http://www.jianshu.com/p/7b5c99e1cfa3

上一篇下一篇

猜你喜欢

热点阅读