Most detailed summary of Toolbar development practices

Prior to 2015, this article always introduces the best practice of always System Bar, receiving many developers’ always attention and feedback. Start writing a second article today that gives a comprehensive introduction to the Toolbar. Speaking of the Toolbar, there may be a lot of development that is unfamiliar, but keep reading.

I met the Toolbar

The Toolbar is a Material Design-style navigation control introduced in Android 5.0. Google highly recommends using the Toolbar as a navigation bar on Android clients instead of the Actionbar. The Toolbar is significantly more flexible than the Actionbar. Unlike the Actionbar, which must be fixed to the top of the Activity, it can be placed anywhere in the interface. In addition, when designing the Toolbar, Google has left developers a lot of room for customizable changes. These properties are detailed in the API documentation, such as:

  • Set the navigation bar icon;
  • Set the App logo;
  • Supports setting title and subtitle;
  • Support to add one or more custom controls;
  • Support Action Menu;

image

All in all, the Toolbar makes me feel more sincere than the Actionbar. How to? Do you already have a general understanding of the Toolbar and feel the urge to try it? Next, we’ll take a step by step look at how to use the Toolbar. .

Start using the Toolbar

The Toolbar was only added in Android 5.0, so it’s only natural for Google to introduce a compatible version of the Toolbar in order to make this design retro-compatible. To this end, we need to introduce appcompat into engineering – v7 compatible package, using android. Support. V7. Widget. The Toolbar. Let’s take a look at the code structure, again with the important parts circled in red:

image

  • ToolbarActivity contains some basic uses of the Toolbar, and ZhiHuActivity is a good imitation of the Toolbar home page after becoming familiar with it.

  • The Layout and Menu folders are the layout and ActionMenu files for the two activities mentioned above, respectively.

  • Values, values-v19, and values-v21 contain some custom theme, which will be explained later.

Let’s take a look at ToolbarActivity in action

image

According to the renderings, from left to right are the navigation bar icon, App logo, title and subtitle, custom control, and ActionMenu mentioned above. Next, let’s look at the layout file and code implementation.

First, add the Toolbar controls we need in the layout file activity_tool_bar.xml

<? xml version="1.0" encoding="utf-8"? > <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/color_0176da"> <! <TextView Android :layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Clock" />
    </android.support.v7.widget.Toolbar>
</LinearLayout>

Copy the code

Then add the Action Menu menu item to base_toolbar_menu.xml

<? xml version="1.0" encoding="utf-8"? > <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_search"
        android:title="@string/menu_search"
        app:showAsAction="ifRoom" />

    <item
        android:id="@id/action_notification"
        android:icon="@mipmap/ic_notifications"
        android:title="@string/menu_notifications"
        app:showAsAction="ifRoom" />

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

    <item
        android:id="@+id/action_item2"
        android:title="@string/item_02"
        app:showAsAction="never" />
</menu>

Copy the code

Finally, call the code in the ToolbarActivity to retrieve the Toolbar control and perform various setXXX operations in the code.

Public class extends BaseActivity {@override protected void onCreate(Bundle) savedInstanceState) { super.onCreate(savedInstanceState);setContentView(R.layout.activity_tool_bar); Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); toolbar.setNavigationIcon(R.mipmap.ic_drawer_home); // Set the navigation icon toolbar. SetLogo (r.map.ic_launcher); // Set app logo toolanto.setTitle ("Title"); // Set the main title tools.setSubTitle ("Subtitle"); // Set the subtitle tool.inflatemenu (r.menu. base_toolbar_menu); / / set menu in the top right corner of the filling toolbar. SetOnMenuItemClickListener (new toolbar.OnMenuItemClickListener() {
            @Override
            public boolean onMenuItemClick(MenuItem item) {
                int menuItemId = item.getItemId();
                if (menuItemId == R.id.action_search) {
                    Toast.makeText(ToolBarActivity.this , R.string.menu_search , Toast.LENGTH_SHORT).show();

                } else if (menuItemId == R.id.action_notification) {
                    Toast.makeText(ToolBarActivity.this , R.string.menu_notifications , Toast.LENGTH_SHORT).show();

                } else if(menuItemId == R.id.action_item1) { Toast.makeText(ToolBarActivity.this , R.string.item_01 , Toast.LENGTH_SHORT).show();  }else if(menuItemId == R.id.action_item2) { Toast.makeText(ToolBarActivity.this , R.string.item_02 , Toast.LENGTH_SHORT).show();  }return true; }}); }}Copy the code

The code at this point has completed basic use of the Toolbar, note that it is only basic use !!!!! Here are a few things to look out for in code:

  1. When using the Toolbar, we need to hide the system’s original navigation bar. Many people on the web say that we should create a NoActionBar Theme for our activities. But personally feel a little make a mountain out of a molehill, so here I directly call in BaseActivity supportRequestWindowFeature (Window. FEATURE_NO_TITLE) remove the navigation bar (note that by default My BaseActivity inherits appactivity, so if it inherits an Activity it should call requestWindowFeature(window.feature_no_title).

  2. If you want to modify the title and subtitle of the font size, color, etc., can be called setTitleTextColor, setTitleTextAppearance, setSubtitleTextColor, setSubtitleTextAppearance these apis;

  3. The custom View is located between title, subtitle, and ActionMenu. This means that if title and subtitle are present and actionMenu options are too numerous, there is less room for the custom View.

  4. What’s the difference between a navigation icon and an app logo? If you only set the navigation icon (or APP logo) and title and subtitle, you will find that the spacing between the app logo and title and subtitle is relatively small, and it looks less beautiful than the navigation icon with them.

  5. The Toolbar, like other controls, has many properties that can be set in code as well as in XML (this is where the worst of the worst comes from, so read on).

Toolbar step on the pit to fill the pit

  • Pit 1: Invalid Toolbar property setting in XML layout file

This is what I wrote in my layout file when I first started using the Toolbar

<? xml version="1.0" encoding="utf-8"? > <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/color_0176da"
        android:logo="@mipmap/ic_launcher"
        android:navigationIcon="@mipmap/ic_drawer_home"
        android:subtitle="456"
        android:title="123"> <! <TextView Android :layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Clock" />
    </android.support.v7.widget.Toolbar>
</LinearLayout>

Copy the code

After the real machine runs, the result looks like this.

image

In addition to setting the background color and TextView effective, said good LOGO, navigationIcon, subtitle, title are running where? When the compiler didn’t report any errors, the solution was to add a namespace for custom attributes to the root layout after consulting other developers

xmlns:toolbar="http://schemas.android.com/apk/res-auto"(The toolbar here can be renamed any other way you want, and will be more familiar to those who have made custom controls.)Copy the code

Then use the Toolbar: XXX Settings to validate all android: XXX Settings. The final layout code looks like this:

<? xml version="1.0" encoding="utf-8"? > <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:toolbar="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/color_0176da"
        toolbar:navigationIcon="@mipmap/ic_drawer_home"
        toolbar:logo="@mipmap/ic_launcher"
        toolbar:subtitle="456"
        toolbar:title="123"> <! <TextView Android :layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Clock" />
    </android.support.v7.widget.Toolbar>
</LinearLayout>

Copy the code

This solves the problem of invalidation of attribute Settings in XML. Why does this happen? Yes, these properties are in the compatibility package, not in the default Android SDK, so we need to introduce additional controls. As for why the IDE does not report errors, it is probably a bug!

  • Pit 2: The Action Menu Item text color setting is invalid

The system implicitly sets the text color and size of each ActionMenu Item. For example, the default effect of ToolbarActivity in Google native 5.1 is as follows

image

At this point, if I need to change the color of item text, how should I break it? According to the common online solution, I made the following two-step modification operation:

  • In styles. The XML in a custom Theme, and set actionMenuTextColor properties (note: not android: actionMenuTextColor)

<style name="Theme.ToolBar.Base" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="actionMenuTextColor">@color/color_red</item>
</style>

Copy the code

  • Set the popupTheme in the Layout file’s Toolbar (Toolbar: XXX, not Android: XXX).

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/color_0176da"
        toolbar:popupTheme="@style/Theme.ToolBar.Base"> <! <TextView Android :layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Clock" />
    </android.support.v7.widget.Toolbar>

Copy the code

After running, the color of the text does not change at all. Said good to change the color….. The actionMenuTextColor attribute is android:textColorPrimary, and the result is the following.

image

There is a minor drawback to this method, too. If I change the custom control to Button, you will see that Button’s default text color also changes to red. So, if any of your friends here have a better solution, please leave a comment.

If you want to change the ActionMenu Item text size, you can also add the following Settings to the theme

<item name="android:textSize">20sp</item>

Copy the code

These are some of the more difficult Toolbar pits, and it feels like Google could further optimize these pits for the Toolbar, otherwise it would be a bitter pit for developers.

Imitation zhihu homepage

To enhance the Toolbar development experience, we use the Toolbar to achieve the effect of zhihu’s home page! Take a look at the effect of Zhihu’s homepage first

image

If the previous content you understand, want to masturbate out of this interface is no more than a few minutes of things, let’s go directly to the code, do not repeat.

ZhiHuActivity interface code

public class ZhiHuActivity extends BaseActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_zhi_hu); Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); toolbar.inflateMenu(R.menu.zhihu_toolbar_menu); toolbar.setNavigationIcon(R.mipmap.ic_drawer_home); toolbar.setTitle(R.string.home_page); toolbar.setTitleTextColor(getResources().getColor(android.R.color.white)); }}Copy the code

Zhihu_toolbar_menu. XML menu

<? xml version="1.0" encoding="utf-8"? > <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_search"
        android:title="@string/menu_search"
        app:showAsAction="ifRoom" />

    <item
        android:id="@id/action_notification"
        android:icon="@mipmap/ic_notifications"
        android:title="@string/menu_notifications"
        app:showAsAction="ifRoom" />

    <item
        android:id="@id/action_settings"
        android:orderInCategory="100"
        android:title="@string/menu_settings"
        app:showAsAction="never" />

    <item
        android:id="@id/action_about"
        android:orderInCategory="101"
        android:title="@string/menu_about_us"
        app:showAsAction="never" />
</menu>

Copy the code

Activity_zhi_hu. XML layout

<? xml version="1.0" encoding="utf-8"? > <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/color_0176da"
        android:theme="@style/Theme.ToolBar.ZhiHu">

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

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@android:color/white">

        <ImageView
            android:layout_width="60dp"
            android:layout_height="60dp"
            android:layout_centerInParent="true"
            android:background="@mipmap/ic_zhihu_logo" />
    </RelativeLayout>

</LinearLayout>

Copy the code

Styles. XML Theme. Tools. ZhiHu, for android: Theme for the ToolBar

<resources> ... . <style name="Theme.ToolBar.ZhiHu" parent="Theme.AppCompat.Light.NoActionBar">
        <item name="actionOverflowButtonStyle">@style/ActionButton.Overflow.ZhiHu</item>
    </style>

    <style name="ActionButton.Overflow.ZhiHu" parent="android:style/Widget.Holo.Light.ActionButton.Overflow">
        <item name="android:src">@mipmap/ic_menu_more_overflow</item>
    </style>

</resources>

Copy the code

You end up with something like this

image

Here in the Toolbar set android: theme = “@ style/theme. The Toolbar. ZhiHu” mainly to replace system three points icon at top right corner, if not set, will be to look like the default theme system.

image

Finally, as a small optimization, ZHIhu always sees a black notification Bar on Android 4.4. For this, I combine the Toolbar and.3. The result is the following (attached with running effects on Android4.4 and 5.1).

image

image

3. If you do not yet know how to always use this characterization, always System Bar, check out my previous article: Best practice, always System Bar

conclusion

So much for using the Toolbar, which was intended to be very easy to use, only to find that there are still a lot of holes to fill. That proves an old saying

The paper come zhongjue shallow, and must know this to practiceCopy the code

Similarly, sharing is virtue, need source code for children’s shoes, please stamp: github.com/D-clock/And…

Author: D_clock love to eat scallions links: www.jianshu.com/p/79604c3dd…