美文网首页
Toolbar和沉浸式基类的封装

Toolbar和沉浸式基类的封装

作者: 耳_总 | 来源:发表于2017-11-27 16:29 被阅读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中间作为中间标题栏。

    • toolbar的菜单
      toobar的菜单和actionbar类似
    <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

    相关文章

      网友评论

          本文标题:Toolbar和沉浸式基类的封装

          本文链接:https://www.haomeiwen.com/subject/wzwmvxtx.html