Android ActionBar和ToolBar的使用

参考

1、android中的ActionBar和ToolBar
2、『Material Design入门学习笔记』主题与AppCompatActivity(附demo)
3、Android开发:最详细的 Toolbar 开发实践总结
4、Toolbar设置详解----掉坑总结

前言

自android5.0开始,AppCompatActivity代替ActionBarActivity,而且ToolBar也代替了ActionBar,下面就是ActionBar和ToolBar的使用

ActionBar

1、截图

image.png

2、使用

2.1、AppCompatActivity和其对应的Theme
  • AppCompatActivity使用的是v7的ActionBar(和默认的ActionBar使用起来略有区别,一会代码中会有体现)
  • Theme的话继承于Theme.AppCompat.Light.DarkActionBar,系统提供的深色系的actionbar,那么按钮,文字,和菜单是白色的
//Activity
public class ActionBarActivity extends AppCompatActivity

//style
<!--默认所有activity的actionbar的theme-->
    <style name="AppCompatActivity_ActionBarTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
        <item name="android:textAllCaps">false</item>
    </style>
2.2、ActionBar的使用
  • 获取actionbar:\color{red}{这里v7的是getSupportActionBar(),默认的是getActionBar()}
        //AppCompatActivity use v7 action bar
        actionBar = this.getSupportActionBar();
        //Activity use action bar
        //actionBar = this.getActionBar();

        if(actionBar == null){
            return;
        }
  • 设置主副标题
        //主标题
        actionBar.setTitle("ActionBar Title");
        //副标题
        actionBar.setSubtitle("Sub Title");
  • 设置navigation up按钮:可见+可用+更换图标
        //左侧按钮:可见+可用+更换图标
        actionBar.setDisplayHomeAsUpEnabled(true);
        actionBar.setHomeButtonEnabled(true);
        //actionBar.setHomeAsUpIndicator(R.mipmap.back_white);
  • 设置navigation up按钮的监听:复写onSupportNavigateUp(),\color{red}{但是如果有menu复写onOptionsItemSelected函数的话,则onSupportNavigateUp()将不会被调用}
/**
     * 复写:左侧按钮点击动作
     * android.R.id.home
     * v7 actionbar back event
     * 注意:如果复写了onOptionsItemSelected方法,则onSupportNavigateUp无用
     * */
    @Override
    public boolean onSupportNavigateUp() {
        finish();
        return super.onSupportNavigateUp();
    }

    /**
     * 复写:左侧按钮点击动作
     * android.R.id.home
     * actionbar back event
     * 注意:如果复写了onOptionsItemSelected方法,则onSupportNavigateUp无用
    @Override
    public boolean onNavigateUp() {
        finish();
        return super.onNavigateUp();
    }* */
  • 设置logo(icon等):用logo代替icon,不知道为什么不灵??
        //设置logo
        actionBar.setLogo(android.R.mipmap.sym_def_app_icon);
        actionBar.setDisplayUseLogoEnabled(true);
        //设置icon:use logo instead of an icon
        //actionBar.setIcon(R.mipmap.ic_launcher);
  • 设置菜单menu和对应监听:android.R.id.home就是左侧的navigation up按钮
   /**
     * 复写:添加菜单布局
     * */
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu, menu);
        return true;
    }

    /**
     * 复写:设置菜单监听
     * */
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
                //actionbar navigation up 按钮
            case android.R.id.home:
                finish();
                break;

            case R.id.action_refresh:
                Toast.makeText(this, "Refresh selected", Toast.LENGTH_SHORT).show();
                break;
            case R.id.action_add:
                Toast.makeText(this, "Add selected", Toast.LENGTH_SHORT).show();
                break;
            case R.id.action_settings:
                Toast.makeText(this, "Settings selected", Toast.LENGTH_SHORT).show();
                break;
            default:
                break;
        }
        return true;
    }
  • 设置tab和对应监听
        //增加actionbar 下面的tab按钮
        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
        actionBar.addTab(actionBar.newTab().setText("Tab 1").setTabListener(new ActionBar.TabListener() {
            @Override
            public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
                Toast.makeText(ActionBarActivity.this, "Tab 1 select",Toast.LENGTH_SHORT).show();
            }
            @Override
            public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) { }
            @Override
            public void onTabReselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) { }
        }));
        actionBar.addTab(actionBar.newTab().setText("Tab 2").setTabListener(new ActionBar.TabListener() {
            @Override
            public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
                Toast.makeText(ActionBarActivity.this, "Tab 2 select",Toast.LENGTH_SHORT).show();
            }
            @Override
            public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) { }
            @Override
            public void onTabReselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) { }
        }));
  • 或者完全自定义
       //自定义
        actionBar.setCustomView(R.layout.actionbar_title);
        actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
  • 隐藏、显示actionbar
case R.id.btn_hide:
                if(actionBar != null){
                    /**
                     * 隐藏actionbar
                     * 1、有actionbar情况下:actionBar.hide();
                     * 2、直接使用Theme.Holo.NoActionBar
                     * 3、theme中添加属性
                     *      <item name="windowActionBar">false</item>
                     *      <item name="windowNoTitle">true</item>
                     * 4、在setContent之前 Window feature must be requested before adding content
                     *    AppCompatActivity: supportRequestWindowFeature(Window.FEATURE_NO_TITLE),
                     *    Activity: requestWindowFeature(Window.FEATURE_NO_TITLE);
                     *
                     * */
                    actionBar.hide();
                }
                break;

            case R.id.btn_show:
                if(actionBar != null){
                    actionBar.show();
                }
                break;

-------------------------------------分割线-------------------------------

Menu(共通的菜单,不细说)

1、showAsAction属性

  • always表示永远显示在ActionBar中,如果屏幕空间不够则无法显示
  • ifRoom表示屏幕空间够的情况下显示在ActionBar中,不够的话就显示在overflow中
  • never则表示永远显示在overflow中
  • withText:这个值使菜单项和它的图标,文本一起显示

2、布局

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:android="http://schemas.android.com/apk/res/android">
    <!--showAsAction属性
        always表示永远显示在ActionBar中,如果屏幕空间不够则无法显示
        ifRoom表示屏幕空间够的情况下显示在ActionBar中,不够的话就显示在overflow中
        never则表示永远显示在overflow中
        withText:这个值使菜单项和它的图标,文本一起显示-->

    <!--menuCategory:同种菜单项的种类。该属性可取4个值:container、system、secondary和alternative。-->

    <!--orderInCategor:同种类菜单的排列顺序。该属性需要设置一个整数值-->

    <item
        android:id="@+id/action_refresh"
        android:icon="@mipmap/refresh"
        android:title="Refresh"
        app:showAsAction="always" />
    <item
        android:id="@+id/action_add"
        android:icon="@mipmap/add"
        android:title="Add"
        app:showAsAction="ifRoom" />
    <item
        android:id="@+id/action_settings"
        android:icon="@mipmap/settings"
        android:title="Settings"
        app:showAsAction="never">
    </item>
</menu>

-------------------------------------分割线-------------------------------

ToolBar

了解了ActionBar的话,那么ToolBar和其差不多,更加强大,更加符合MD风格,然后就代替ActionBar,使用起来差不多,但是又UI上的坑

1、截图:颜色不正常的

image.png

2、使用

2.1、隐藏ActionBar有4中方式
  • 1、如果继承了theme有actionbar的则,在setContentView方法之前设置:v7的supportRequestWindowFeature(Window.FEATURE_NO_TITLE);或者非v7的requestWindowFeature(Window.FEATURE_NO_TITLE);
  • 2、theme直接继承没有actionbar的,比如说:Theme.AppCompat.Light.NoActionBar
  • 3、theme中没设置属性没有actionbar:<item name="windowActionBar">false</item>
    <item name="windowNoTitle">true</item>
  • 4、actionBar.hide();
2.2、AppCompatActivity和其对应的Theme
//activity
public class ToolBarActivity extends AppCompatActivity

//style
    <!--默认所有activity的toolbar的theme-->
    <!--<style name="AppCompatActivity_ToolBarTheme" parent="Theme.AppCompat.Light.NoActionBar">-->
    <style name="AppCompatActivity_ToolBarTheme" parent="Theme.AppCompat.Light">
        <!--不要actionbar,不要title-->
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>

        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
        <item name="android:textAllCaps">false</item>
    </style>
ToolBar的使用
  • toolbar在layout中布局代码:
    \color{red}{这里面有UI的坑,就是深色toolbar,文字也是黑色的,难看}
<!--这里是代替actionbar的,当然可以设置在baseactivity中通用,然后include进来-->
    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:background="?attr/colorPrimary"
        android:layout_height="wrap_content"
        android:minHeight="?attr/actionBarSize">

    </android.support.v7.widget.Toolbar>
  • 获取toolbar并取代actionbar,这里设置toolbar的标题必须在setSupportActionBar之前,否则无用
       //隐藏默认actionbar
        ActionBar actionBar = getSupportActionBar();
        if(actionBar != null){
            actionBar.hide();
        }

        //获取toolbar
        toolBar = findViewById(R.id.toolbar);
        //主标题,必须在setSupportActionBar之前设置,否则无效,如果放在其他位置,则直接setTitle即可
        toolBar.setTitle("ToolBar Title");
        //用toolbar替换actionbar
        setSupportActionBar(toolBar);
  • 设置副标题
        //副标题+颜色
        toolBar.setSubtitle("Sub Title");
  • 设置navigation up按钮的图标和点击监听
        //左侧按钮:可见+更换图标+点击监听
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);//显示toolbar的返回按钮
        //toolBar.setNavigationIcon(R.mipmap.back_white);
        toolBar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });
       
  • 设置logo
         //设置logo
        toolBar.setLogo(android.R.mipmap.sym_def_app_icon); 
  • 设置菜单menu及其监听
/**
     * 复写:添加菜单布局
     * */
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu, menu);
        return true;
    }

    /**
     * 复写:设置菜单监听
     * */
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.action_refresh:
                Toast.makeText(this, "Refresh selected", Toast.LENGTH_SHORT).show();
                break;
            case R.id.action_add:
                Toast.makeText(this, "Add selected", Toast.LENGTH_SHORT).show();
                break;
            case R.id.action_settings:
                Toast.makeText(this, "Settings selected", Toast.LENGTH_SHORT).show();
                break;
            default:
                break;
        }
        return true;
    }
       
  • 加载自定义toolbar:直接在toolbar的layout中写即可,可以是文字居中等等
  • 隐藏、显示toolbar
 case R.id.btn_hide:
                if(toolBar != null){
                    toolBar.setVisibility(View.GONE);
                }
                break;

            case R.id.btn_show:
                if(toolBar != null){
                    toolBar.setVisibility(View.VISIBLE);
                }
                break;

3、截图:颜色正常的

4、用ToolBar 的Theme和PopupTheme来控制颜色正常,或自定义颜色

4.1、ToolBar显然颜色不对,那找找为啥ActionBar的时候对的,直觉告诉我是theme的问题,于是找Theme.AppCompat.Light.DarkActionBar,点击进去看会看到
  • actionBarPopupThem是Light的,就是menu菜单点击弹出那个
  • actionBarTheme是深色系的,那么控制按钮图标和主副标题颜色就是白色的
<style name="Base.Theme.AppCompat.Light.DarkActionBar" parent="Base.Theme.AppCompat.Light">
        <item name="actionBarPopupTheme">@style/ThemeOverlay.AppCompat.Light</item>
        <item name="actionBarWidgetTheme">@null</item>
        <item name="actionBarTheme">@style/ThemeOverlay.AppCompat.Dark.ActionBar</item>

        <!-- Panel attributes -->
        <item name="listChoiceBackgroundIndicator">@drawable/abc_list_selector_holo_dark</item>

        <item name="colorPrimaryDark">@color/primary_dark_material_dark</item>
        <item name="colorPrimary">@color/primary_material_dark</item>
    </style>
4.2、新建Toolbar的theme和popuptheme:这里面就是继承刚刚找到的东西,当然也可以再自定义颜色咯
    <!--给toolbar单独设置的theme,让toolbar上按钮颜和文字颜色变化的-->
    <style name="MyDarkToolBarTheme" parent="ThemeOverlay.AppCompat.Dark.ActionBar">
        <!--toolbar图标颜色-->
        <!--<item name="colorControlNormal">@color/colorAccent</item>-->
        <!--toolbar的title颜色-->
        <!--<item name="android:textColorPrimary">@color/colorAccent</item>-->
        <!--toolbar的subtitle颜色-->
        <!--<item name="subtitleTextColor">@color/colorAccent</item>-->
    </style>

    <!--给toolbar的menu内单独设置的theme,让toolbar上按钮颜和文字颜色变化的-->
    <style name="MyLightPopupTheme" parent="ThemeOverlay.AppCompat.Light">
        <!--设置背景-->
        <!--<item name="android:background">@android:color/white</item>-->
        <!--设置字体颜色-->
        <!--<item name="android:textColor">@color/colorAccent</item>-->
        <!--设置不覆盖锚点-->
        <!--<item name="overlapAnchor">false</item>-->
    </style>
4.3、添加Toolbar的theme和popuptheme
//需添加
xmlns:app="http://schemas.android.com/apk/res-auto"

<!--这里是代替actionbar的,当然可以设置在baseactivity中通用,然后include进来-->
    <android.support.v7.widget.Toolbar
        省略...
        app:theme="@style/MyDarkToolBarTheme"
        app:popupTheme="@style/MyLightPopupTheme">

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

大功告成

以上就是ActionBar和ToolBar的入门使用,后面配合上系统的StatusBar和NavigationBar,并实现沉浸式还有的烦,但这些都属于基础部分,得打牢UI基础。

友情链接>>> Android 沉浸式风格(为毛叫沉浸式这么唬人)

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

推荐阅读更多精彩内容