The most detailed explanation of Toolbar development in history, this is a must-read!

The most detailed explanation of Toolbar development in history, this is a must-read!

Introduction to Toolbar

Toolbar is a new control introduced in Android 5.0. Before Toolbar appeared, we often used ActionBar and ActionActivity to implement the top navigation bar. Therefore, Toolbar can be understood as an upgraded version of ActionBar. Toolbar greatly expands ActionBar and is more flexible to use. Unlike ActionBar, Toolbar is more like a general View element. It can be placed anywhere in the view tree system, can be animated, can scroll with scrollView, and can interact with other views in the layout.

Basic Use of Toolbar

1. To use Toolbar, you should first add the V7 compatible package to the Gradle configuration script (the code is as follows, the version is the version when Nanmei wrote this article), or use the operation method of the graphical interface of Android Studio to depend on the V7 compatible package.

  1. compile 'com.android.support:appcompat-v7:23.1.1'  

2. Add Toolbar to the layout file where we need the top navigation bar, and configure some common properties (when using custom properties, be sure to add the namespace "app" to the root node).

  1. xmlns:app= "http://schemas.android.com/apk/res-auto"  

Here we only list some commonly used attributes, such as minimum height, back button icon, background, etc. It should be noted that the "?" in the attribute value indicates that the Android system theme style is reused. This means that if we change the colorPrimary attribute in the theme style, the background color of the Toolbar will also change, so we are reminded to make some configurations in the theme style.

  1. <android.support.v7.widget.Toolbar
  2. android:id= "@+id/toolbar"  
  3. android:layout_width= "match_parent"  
  4. android:layout_height= "wrap_content"  
  5. android:background= "?attr/colorPrimary"  
  6. android:minHeight= "?actionBarSize"  
  7. app:navigationIcon= "@mipmap/arrow_left"  
  8. app:title= "title" />

3. Make some common configurations in the styles.xml file. Since we are using

AppCompatActivity, so you must use the related themes of AppCompat. Here I use a bright theme without ActionBar. Note that you need to use your own theme in the manifest file. In order to completely remove the ActionBar, you need to write windowActionBar, windowNoTitle, and add the android declaration to ensure that the ActionBar that comes with the system and the third-party compatibility package are completely removed.

  1. < style   name = "AppTheme"   parent = "Theme.AppCompat.Light.NoActionBar" >  
  2. < item   name = "colorPrimary" > @color/red </ item >  
  3. < item   name = "colorPrimaryDark" > @color/green </ item >  
  4. < item   name = "colorAccent" > @color/blue </ item >  
  5. < item   name = "android:textColorPrimary" > @color/white </ item >  
  6.  
  7. < item   name = "android:windowActionBar" > false </ item >  
  8. < item   name = "android:windowNoTitle" > true </ item >  
  9.  
  10. < item   name = "windowActionBar" > false </ item >  
  11. < item   name = "windowNoTitle" > true </ item >  
  12. </ style >  

4. The following is an explanation of several colors in the theme. Please refer to the pictures below for understanding.

  • colorPrimaryDark is the background color of the status bar at the top of our phone (changing it requires support from Android 5.0 and above phones).
  • colorPrimary refers to the color of the navigation bar.
  • colorAccent refers to the color of our commonly used controls such as Button.
  • textColorPrimary refers to the color of the title in our navigation bar.
  • WindowBackground refers to the default color of our window.
  • navigationBarColor refers to the background color of the virtual buttons in Android phones.

5. Perform common operations on Toolbar in the code. After finding Toolbar by ID, you can listen to clicks on the navigation icon, provided that the navigation icon has been added in the layout file or Java code. The menu can also be used in the same way. Please refer to the comments for details.

  1. Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
  2.  
  3. //Monitor the navigation icon on the left side of the Toolbar
  4. toolbar.setNavigationOnClickListener(new View .OnClickListener() {
  5. @Override
  6. public void onClick( View v) {
  7. Toast.makeText(MainActivity.this, "return" , Toast.LENGTH_SHORT).show();
  8. }
  9. });
  1. //Use menu in Toolbar toolbar.inflateMenu(R.menu.menu_main);
  2. toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
  3. @Override
  4. public boolean onMenuItemClick(MenuItem item) {
  5. switch (item.getItemId()) {
  6. case R.id.action_item1:
  7. Toast.makeText(MainActivity.this, "Menu 1" , Toast.LENGTH_SHORT).show();
  8. return   true ;
  9. case R.id.action_item2:
  10. Toast.makeText(MainActivity.this, "Menu 2" , Toast.LENGTH_SHORT).show();
  11. return   true ;
  12.  
  13. case R.id.action_item3:
  14. Toast.makeText(MainActivity.this, "Menu 3" , Toast.LENGTH_SHORT).show();
  15. return   true ;
  16. } return   false ;
  17.  
  18. }
  19. });

6. Operation effect diagram

Toolbar Advanced Use - Customizing Toolbar

From the comparison below, we can see that the native Toolbar screen is too beautiful to look at directly. Generally speaking, if we want to use Toolbar in a project, we should customize it. Let's start discussing how to customize Toolbar.

Let me give you the core points:

  • Customize the layout and add it to the Toolbar
  • Customize some properties when necessary
  • The custom Class inherits Toolbar, reads custom properties, sets the layout and content of Toolbar, and finally needs to expose some functions to set titles, listeners, etc. The following steps are explained in detail.

1. Write a custom layout to put in the custom Toolbar.

  1. <?xml version= "1.0" encoding= "utf-8" ?>
  2.  
  3. <RelativeLayout
  4. xmlns:android= "http://schemas.android.com/apk/res/android"  
  5. android:layout_width= "match_parent"  
  6. android:layout_height= "wrap_content"  
  7. >
  8.  
  9. <RelativeLayout
  10. android:layout_width= "match_parent"  
  11. android:layout_height= "wrap_content"  
  12. android:layout_marginLeft= "10dp"  
  13. android:layout_marginRight= "10dp" >
  14.  
  15. <ImageView
  16. android:id= "@+id/toolbar_leftButton"  
  17. android:layout_width= "@dimen/icon_size"  
  18. android:layout_height= "@dimen/icon_size"  
  19. android:layout_alignParentLeft= "true"  
  20. android:layout_centerVertical= "true"  
  21. android:src= "@mipmap/icon_background"  
  22. android:textColor= "@color/white"  
  23. android:visibility= "visible"  
  24. />
  25.  
  26. <ImageView
  27. android:id= "@+id/toolbar_rightButton"  
  28. android:layout_width= "@dimen/icon_size"  
  29. android:layout_height= "@dimen/icon_size"  
  30. android:layout_alignParentRight= "true"  
  31. android:layout_centerVertical= "true"  
  32. android:src= "@mipmap/icon_background"  
  33. android:textColor= "@color/white"  
  34. android:visibility= "visible"  
  35. />
  36.  
  37. <EditText
  38. android:id= "@+id/toolbar_searchview"  
  39. style= "@style/search_view"  
  40. android:layout_width= "match_parent"  
  41. android:layout_height= "wrap_content"  
  42. android:layout_centerVertical= "true"  
  43. android:layout_gravity= "center"  
  44. android:layout_marginLeft= "10dp"  
  45. android:layout_marginRight= "10dp"  
  46. android:layout_toLeftOf= "@id/toolbar_rightButton"  
  47. android:layout_toRightOf= "@id/toolbar_leftButton"  
  48. android:drawableLeft= "@mipmap/icon_search"  
  49. android:gravity= "center"  
  50. android:hint= "Please enter the search content"  
  51. android:visibility= "gone"  
  52. />
  53.  
  54. <TextView
  55. android:id= "@+id/toolbar_title"  
  56. android:layout_width= "match_parent"  
  57. android:layout_height= "wrap_content"  
  58. android:layout_centerInParent= "true"  
  59. android:layout_gravity= "center"  
  60. android:layout_marginLeft= "10dp"  
  61. android:layout_marginRight= "10dp"  
  62. android:layout_toLeftOf= "@id/toolbar_rightButton"  
  63. android:layout_toRightOf= "@id/toolbar_leftButton"  
  64. android:gravity= "center"  
  65. android:textColor= "@color/white"  
  66. android:textSize= "20sp"  
  67. android:visibility= "gone"  
  68. />
  69.  
  70. </RelativeLayout>
  71.  
  72. </RelativeLayout>

Let us explain it through the following two effect pictures O(∩_∩)O~~.

Since it is generally not recommended to write attributes other than width and height in the outermost root node, I embedded a relative layout in the outermost relative layout and set the left and right margins. As for how to layout, it depends on the actual project. Nan's requirement here is that the title and search box can be switched at any time. Therefore, the title and search box are overlapped through the project layout, and when one of them is needed, the other is hidden. Another thing to note is that the left and right buttons should not be used by the Toolbar, because it may cause an asymmetric layout and make the title (search box) not centered. When the button is not in use, we do not hide it through the gone method, but use the @mipmap/icon_background blank image to take up space to keep the layout symmetrical.

2. Create a new attrs.mxl file in the values ​​folder to store some custom attributes. These attributes can be understood by their literal meanings, so I won’t explain them in detail.

  1. <?xml version= "1.0" encoding= "utf-8" ?>
  2. <resources>
  3. < declare -styleable name = "CNToolbar" >
  4. <attr name = "showSearchView" format = "boolean" />
  5. <attr name = "leftButtonIcon" format = "reference" />
  6. <attr name = "rightButtonIcon" format= "reference" />
  7. <attr name = "myTitle" format = "string" />
  8. </declare-styleable>
  9.  
  10. </resources>

3. Customize the Class to inherit Toolbar. The main work of the code is to initialize the interface and listener, and open the interface for external operations.

When initializing the interface, you need to read the value of the custom attribute through TintTypedArray, and then make some settings for the interface display.

To initialize the listener, you need to use the callback of the interface. The specific steps are to publicly declare the interface, which has an onClick method; declare the implementation of the interface as a private member variable of the Toolbar; publicly declare the setListener method and assign the passed Listener implementation class to this member variable; call the onClick method of the member variable when necessary (such as calling it in the click event of the button on the left).

Expose some functions, such as setting the title, setting whether to display the search box, title, etc.

  1. /**
  2. * Customized navigation bar
  3. */ public class CNToolbar extends Toolbar {
  4. private TextView toolbar_title;
  5. private EditText toolbar_searchview;
  6. private ImageView toolbar_leftButton;
  7. private ImageView toolbar_rightButton;
  8. private View mChildView;
  9. private boolean showSearchView;
  10. private Drawable left_button_icon;
  11. private Drawable right_button_icon;
  12. private String title;
  13. public CNToolbar(Context context) {
  14. this(context, null , 0);
  15. } public CNToolbar(Context context, @Nullable AttributeSet attrs) {
  16. this(context, attrs, 0);
  17. } public CNToolbar(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
  18. super(context, attrs, defStyleAttr); //Get the values ​​of some attributes in the layout file through code
  19. final TintTypedArray a = TintTypedArray.obtainStyledAttributes(getContext(), attrs,
  20. R.styleable.CNToolbar, defStyleAttr, 0);
  21. showSearchView = a.getBoolean(R.styleable.CNToolbar_showSearchView, false );
  22. left_button_icon = a.getDrawable(R.styleable.CNToolbar_leftButtonIcon);
  23. right_button_icon = a.getDrawable(R.styleable.CNToolbar_rightButtonIcon);
  24. title = a.getString(R.styleable.CNToolbar_myTitle);
  25. a.recycle(); //initial interface
  26. initView(); //Initial listener
  27. initListener();
  28. } /**
  29. * Initialize layout
  30. */
  31. private void initView() {
  32. if (mChildView == null ) {
  33. mChildView = View .inflate(getContext(), R.layout.toolbar, null );
  34.  
  35. toolbar_title = (TextView) mChildView.findViewById(R.id.toolbar_title);
  36. toolbar_searchview = (EditText) mChildView.findViewById(R.id.toolbar_searchview);
  37. toolbar_leftButton = (ImageView) mChildView.findViewById(R.id.toolbar_leftButton);
  38. toolbar_rightButton = (ImageView) mChildView.findViewById(R.id.toolbar_rightButton);
  39. //Add a custom layout to the Toolbar
  40. addView(mChildView); //Set whether the title, search box, left and right buttons are displayed, and set the button icons
  41. if (showSearchView) {
  42. showSearchview();
  43. hideTitle();
  44. } else {
  45. hideSearchview();
  46. showTitle();
  47. if (title != null ) {
  48. toolbar_title.setText(title);
  49. }
  50. } if (left_button_icon != null ) {
  51. toolbar_leftButton.setImageDrawable(left_button_icon);
  52. } if (right_button_icon != null ) {
  53. toolbar_rightButton.setImageDrawable(right_button_icon);
  54. }
  55. }
  56.  
  57. } /**
  58. * Rewrite the method to set the title
  59. *
  60. * @param title
  61. */
  62. @Override
  63. public void setTitle(CharSequence title) {
  64. toolbar_title.setText(title);
  65. } @Override
  66. public void setTitle(@StringRes int resId) {
  67. toolbar_title.setText(resId);
  68. } /**
  69. * Set the icons for the left and right buttons
  70. *
  71. * @param d
  72. */
  73. public void setLeftButtonIconDrawable(Drawable d) {
  74. toolbar_leftButton.setImageDrawable(d);
  75. } public void setRightButtonIconDrawable(Drawable d) {
  76. toolbar_rightButton.setImageDrawable(d);
  77. } /**
  78. * Switch between title and search box
  79. */
  80. public void setShowSearchView() {
  81. hideTitle();
  82. showSearchview();
  83. } public void setShowTitleView(String title) {
  84. hideSearchview();
  85. showTitle();
  86. toolbar_title.setText(title);
  87. } /**
  88. * Left and right button monitoring
  89. */
  90. private void initListener() {
  91. toolbar_leftButton.setOnClickListener(new OnClickListener() {
  92. @Override
  93. public void onClick( View v) {
  94. if (onLeftButtonClickListener != null ) {
  95. onLeftButtonClickListener.onClick();
  96. }
  97. }
  98. });
  99.  
  100. toolbar_rightButton.setOnClickListener(new OnClickListener() {
  101. @Override
  102. public void onClick( View v) {
  103. if (onRightButtonClickListener != null ) {
  104. onRightButtonClickListener.onClick();
  105. }
  106. }
  107. });
  108. } public interface OnLeftButtonClickListener {
  109. void onClick();
  110. } public interface OnRightButtonClickListener {
  111. void onClick();
  112.  
  113. } private OnLeftButtonClickListener onLeftButtonClickListener;
  114. private OnRightButtonClickListener onRightButtonClickListener;
  115. public void setOnLeftButtonClickListener(OnLeftButtonClickListener listener) {
  116. onLeftButtonClickListener = listener;
  117. } public void setOnRightButtonClickListener(OnRightButtonClickListener listener) {
  118. onRightButtonClickListener = listener;
  119. } /**
  120. * Set whether the title or search box is displayed
  121. */
  122. private void showTitle() {
  123. toolbar_title.setVisibility( View .VISIBLE);
  124. } private void hideTitle() {
  125. toolbar_title.setVisibility( View .GONE);
  126. } private void showSearchview() {
  127. toolbar_searchview.setVisibility( View .VISIBLE);
  128. } private void hideSearchview() {
  129. toolbar_searchview.setVisibility( View .GONE);
  130. }
  131. }
  132.  
  133. 4. Use it like a general control where necessary. Pay attention to adding the namespace of the custom attribute, which is usually auto.
  134.  
  135. <?xml version= "1.0" encoding= "utf-8" ?>
  136. <LinearLayout xmlns:android= "http://schemas.android.com/apk/res/android"  
  137. xmlns:app= "http://schemas.android.com/apk/res-auto"  
  138. android:layout_width= "match_parent"  
  139. android:layout_height= "match_parent"  
  140. android:orientation= "vertical" >
  141.  
  142. <com.nan.cnshop.widget.CNToolbar
  143. android:id= "@+id/toolbar"  
  144. android:layout_width= "match_parent"  
  145. android:layout_height= "wrap_content"  
  146. android:background= "?attr/colorPrimary"  
  147. android:minHeight= "?actionBarSize"  
  148. app:leftButtonIcon= "@mipmap/icon_back_32px"  
  149. app:showSearchView= "false"  
  150. app:myTitle= "Home"  
  151. />
  152.  
  153. <WebView
  154. android:id= "@+id/webview"  
  155. android:layout_width= "match_parent"  
  156. android:layout_height= "match_parent"  
  157. />
  158. </LinearLayout>

4. Use it like a general control where necessary. Pay attention to adding the namespace of the custom attribute, which is usually auto.

  1. <?xml version= "1.0" encoding= "utf-8" ?>
  2. <LinearLayout xmlns:android= "http://schemas.android.com/apk/res/android"  
  3. xmlns:app= "http://schemas.android.com/apk/res-auto"  
  4. android:layout_width= "match_parent"  
  5. android:layout_height= "match_parent"  
  6. android:orientation= "vertical" >
  7.  
  8. <com.nan.cnshop.widget.CNToolbar
  9. android:id= "@+id/toolbar"  
  10. android:layout_width= "match_parent"  
  11. android:layout_height= "wrap_content"  
  12. android:background= "?attr/colorPrimary"  
  13. android:minHeight= "?actionBarSize"  
  14. app:leftButtonIcon= "@mipmap/icon_back_32px"  
  15. app:showSearchView= "false"  
  16. app:myTitle= "Home"  
  17. />
  18.  
  19. <WebView
  20. android:id= "@+id/webview"  
  21. android:layout_width= "match_parent"  
  22. android:layout_height= "match_parent"  
  23. />
  24. </LinearLayout>

It can also be used in the code, so I won’t go into details.

  1. final CNToolbar toolbar = (CNToolbar) v.findViewById(R.id.toolbar);
  2.  
  3. toolbar.setOnLeftButtonClickListener(new CNToolbar.OnLeftButtonClickListener() {
  4. @Override
  5. public void onClick() {
  6. toolbar.setShowSearchView();
  7. }
  8. });

<<:  It turns out that it is Dialog that causes memory leaks in Android

>>:  Enable HSTS to force the browser to redirect to HTTPS access

Recommend

Unbelievable! He had gone through so much before getting on the train!

Some time ago Cotton blossoms into a sea of ​​flo...

How to create an App promotion landing page with high conversion rate?

This article lists the common forms of app promot...

Case solved! Movie theaters generally have red seats because of this...

When watching a movie, have you ever noticed the ...

​Pay close attention: Will "Delta Plus" trigger another global outbreak?

Recently, the number of confirmed cases of COVID-...

The "dark mode" you see in iOS 13 is actually not eye protection

The bright white background is gradually being re...

Data Structure of Information Olympiad

Brief introduction to the data structure resource...

"The Two Johns" A Parable about Creativity

If Elon Musk is the idol of all entrepreneurs, th...