Android Learning Road (11) Use of ActionBar and ToolBar

Since android 5.0, AppCompatActivity replaces ActionBarActivity, and ToolBar also replaces ActionBar. The following is the use of ActionBar and ToolBar.

ActionBar

1. Screenshot

2. Use

2.1. AppCompatActivity and its corresponding Theme

  • AppCompatActivity uses the ActionBar of v7 (it is slightly different from the default ActionBar, which will be reflected in the code later)
  • Theme inherits from Theme.AppCompat.Light.DarkActionBar. The system provides a dark actionbar, so the buttons, text, and menus are white.
//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. Use of ActionBar

  • Get actionbar:

The v7 here is getSupportActionBar(), the default is getActionBar()

//AppCompatActivity use v7 action bar
actionBar = this.getSupportActionBar();
//Activity use action bar
//actionBar = this.getActionBar();

if(actionBar == null){
    return;
}
  • Set main and subtitles
//主标题
actionBar.setTitle("ActionBar Title");
//副标题
actionBar.setSubtitle("Sub Title");
  • Set navigation up button: visible + available +

But if there is a menu that overrides the onOptionsItemSelected function, then onSupportNavigateUp will not be called.

//左侧按钮:可见+可用+更换图标
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setHomeButtonEnabled(true);
//actionBar.setHomeAsUpIndicator(R.mipmap.back_white);
  • Set up the navigation up button monitoring: override 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();
}**/
  • Set logo (icon, etc.): Use logo instead of icon. I don’t know why it doesn’t work? ?
//设置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);
  • Set the menu menu and corresponding monitoring: android.R.id.home is the navigation up button on the left
/**
 * 复写:添加菜单布局
 * */
@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;
}

Set tab and corresponding monitoring

//增加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) { }
}));
  • Or completely customize
//自定义
actionBar.setCustomView(R.layout.actionbar_title);
actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
  • Hide and show 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 (common menu, not detailed)

1. showAsAction attribute

  • always means it will always be displayed in the ActionBar. If there is not enough screen space, it cannot be displayed.
  • ifRoom means that if the screen space is enough, it will be displayed in the ActionBar. If it is not enough, it will be displayed in the overflow.
  • never means it will always be displayed in the overflow.
  • withText: This value causes the menu item to be displayed together with its icon and text

2. Layout

<?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

If you understand ActionBar, then ToolBar is similar to it, more powerful and more in line with the MD style, and then it replaces ActionBar. It is similar to use, but has UI pitfalls.

1. Screenshot: The color is abnormal

2. Use

2.1. There are 4 ways to hide ActionBar

1. If the theme has an actionbar inherited, set it before the setContentView method: v7 supportRequestWindowFeature(Window.FEATURE_NO_TITLE); or non-v7 requestWindowFeature(Window.FEATURE_NO_TITLE); 2. Theme directly
inherits the theme without actionbar, for example: Theme .AppCompat.Light.NoActionBar
3. There is no attribute set in the theme and no actionbar: false
true
4. actionBar.hide();

2.2. AppCompatActivity and its corresponding 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>

Use of ToolBar

  • Toolbar layout code in layout:

There are UI pitfalls here, that is, the dark toolbar and black text.

<!--这里是代替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>
  • Get the toolbar and replace the actionbar. The title of the toolbar set here must be before setSupportActionBar, otherwise it will be useless.
       //隐藏默认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
  • Set subtitle
        //副标题+颜色
        toolBar.setSubtitle("Sub Title");
  • Set the navigation up button icon and click listener
        //左侧按钮:可见+更换图标+点击监听
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);//显示toolbar的返回按钮
        //toolBar.setNavigationIcon(R.mipmap.back_white);
        toolBar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });
  • Set logo
        //设置logo
        toolBar.setLogo(android.R.mipmap.sym_def_app_icon); 
  • Set menu menu and its monitoring
/**
     * 复写:添加菜单布局
     * */
    @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;
    }
  • Load a custom toolbar: just write it directly in the layout of the toolbar, the text can be centered, etc.
  • Hide and show 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. Screenshot: normal color

4. Use ToolBar’s Theme and PopupTheme to control the normal color or customize the color.

4.1. ToolBar is obviously the wrong color

Then when I looked for the ActionBar, I found it wrong. My intuition told me that it was a problem with the theme, so I looked for Theme.AppCompat.Light.DarkActionBar and clicked in to see what I saw.

  • actionBarPopupThem is Light, which is what pops up when the menu menu is clicked.
  • The actionBarTheme is dark, so the control button icon and main and subtitle colors are white.
<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. Create new Toolbar theme and popuptheme

This is where you inherit what you just found. Of course, you can also customize the color.

    <!--给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. Add Toolbar’s theme and 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>

Guess you like

Origin blog.csdn.net/qq_32907491/article/details/132525697