For more information on the Use of toolbar, please visit toolbar use the detailed series
From toolbar use Step by Step Analysis toolbar source code
Approximate structure
API 0. Setting the navigation icon
Mtoolbar.setnavigationicon (R.drawable.ic_actionbar_flow);
The source code is as follows
public void Setnavigationicon (int resId) { This.setnavigationicon (this.mTintManager.getDrawable (resId)); }
Setnavigationicon
public void Setnavigationicon (@Nullable drawable icon) { if (icon! = null) { this.ensurenavbuttonview (); if (this.mNavButtonView.getParent () = = null) { this.addsystemview (this.mnavbuttonview); This.updatechildvisibilityforexpandedactionview (This.mnavbuttonview); } } else if (This.mnavbuttonview! = null && this.mNavButtonView.getParent ()! = null) { This.removeview ( This.mnavbuttonview); } if (This.mnavbuttonview! = null) { this.mNavButtonView.setImageDrawable (icon);} }
First determine if the incoming picture parameter is NULL
- Null to remove the navigation picture.
- Not NULL, create a new ImageView, set its layoutparams, and finally set the ImageView picture as the entry parameter.
Ensurenavbuttonviewensure that the navigation picture is not NULL, and NULL is new and added.
private void Ensurenavbuttonview () { if (This.mnavbuttonview = = null) { This.mnavbuttonview = new ImageButton ( This.getcontext (), (AttributeSet) null, attr.toolbarnavigationbuttonstyle); Toolbar.layoutparams LP = This.generatedefaultlayoutparams (); lp.gravity = 8388611 | This.mbuttongravity &; THIS.MNAVBUTTONVIEW.SETLAYOUTPARAMS (LP); } }
Set the navigation icon by layoutparams.gravity
lp.gravity=8388611 set Gravity=start that is the left start position
Gravity is initialized within the toolbar constructor.
This.mbuttongravity = 48;
48:gravity = Top
&112 = Get the longitudinal position of the gravity
Set the navigation coordinates in the top left position
A detailed description of the gravity
Continue to determine if the parent form is null
Addsystemview
private void Addsystemview (View v) { Android.view.ViewGroup.LayoutParams VLP = V.getlayoutparams (); Toolbar.layoutparams LP; if (VLP = = null) { LP = This.generatedefaultlayoutparams (); } else if (!this.checklayoutparams (VLP)) { LP = This.generatelayoutparams (VLP); } else { LP = (toolbar.layoutparams) VLP; } Lp.mviewtype = 1; This.addview (v, LP); }
Because toolbar inherits from ViewGroup, when the parent form of the navigation icon is null, the icon is added to the toolbar.Updatechildvisbilityforexpandedactionviewset the navigation icon to visible
API 1.setNavifationOnClickListenerThe source code is as follows
public void Setnavigationonclicklistener (Onclicklistener listener) { this.ensurenavbuttonview (); This.mNavButtonView.setOnClickListener (listener); }
Ensurenavbuttonview above has made a noteSetonclicklistenerThis.mnavbuttonview is ImageView, this is simply a click on the button to set a listener event. API 2.setTitle
public void Settitle (charsequence title) { if (! Textutils.isempty (title)) {
<span style= "White-space:pre" ></span>//title NOT null if (This.mtitletextview = = null) {
<span style= "White-space:pre" ></span>//if the main title TextView does not exist then new Context context = This.getcontext (); This.mtitletextview = new TextView (context); This.mTitleTextView.setSingleLine (); This.mTitleTextView.setEllipsize (truncateat.end); if (this.mtitletextappearance! = 0) { this.mTitleTextView.setTextAppearance (context, this.mtitletextappearance) ; } if (This.mtitletextcolor! = 0) {
<span style= "White-space:pre" ></span>//set Font color this.mTitleTextView.setTextColor ( This.mtitletextcolor); } } if (this.mTitleTextView.getParent () = = null) {
<span style= "White-space:pre" ></span>//if the parent form is NULL, add the main caption TextView, with the navigation icon This.addsystemview ( This.mtitletextview);
<span style= "White-space:pre" ></span>//also updated to visible state This.updatechildvisibilityforexpandedactionview (This.mtitletextview); } } else if (This.mtitletextview! = null && this.mTitleTextView.getParent () = null) {
<span style= "White-space:pre" ></span>//title is null removes the TextView this.removeview of the main header ( This.mtitletextview); } if (This.mtitletextview! = null) {
<span style= "White-space:pre" ></span>//the existence of the main title TextView set the text This.mTitleTextView.setText (title); }
<span style= "White-space:pre" ></span>//set current file This.mtitletext = title;
API 3.setSubTitle, Settitletextcolor, SetsubtitletextcolorThe principle is like Settitle no longer repeat. API 4.inflateMenu
public void Inflatemenu (int resId) { this.getmenuinflater (). Inflate (ResId, This.getmenu ()); }
The final call is the Supportmenuinflater.inflate method
public void Inflate (int menures, menu menu) { if (!) ( Menu instanceof Supportmenu)) {
<span style= "White-space:pre" ></span>//getmenu method is described below, first remember GetMenu return is Supportmenu implementation class Super.inflate (menures, menu); } else { Xmlresourceparser parser = null; try { parser = this.mContext.getResources (). GetLayout (menures); AttributeSet e = xml.asattributeset (parser);
<span style= "White-space:pre" ></span>//analysis Menu.xml file, add MenuItem this.parsemenu to menu (parser, E, menu); } catch (Xmlpullparserexception var9) { throw new inflateexception ("Error inflating menu XML", VAR9); } catch (Ioex Ception var10) { throw new inflateexception ("Error inflating menu XML", var10); } finally { if (parser! = Nu ll) { parser.close ();}}}}
GetMenu
Public Menu GetMenu () { this.ensuremenu (); return This.mMenuView.getMenu (); }
Ensuremenu
private void Ensuremenu () { this.ensuremenuview (); if (this.mMenuView.peekMenu () = = null) {
<span style= "White-space:pre" ></span>//immersive menu is empty menubuilder menu = (menubuilder) This.mMenuView.getMenu (); if (This.mexpandedmenupresenter = = null) {
<span style= "White-space:pre" ></span>//Create an immersive menu for each menu item this.mexpandedmenupresenter = new Toolbar.expandedactionviewmenupresenter (null); } <span style= "White-space:pre" ></span>//Show menu this.mMenuView.setExpandedActionViewsExclusive (True ); Menu.addmenupresenter (This.mexpandedmenupresenter, This.mpopupcontext); } }
Ensuremenuview
private void Ensuremenuview () { if (This.mmenuview = = null) { This.mmenuview = new Actionmenuview ( This.getcontext ()); This.mMenuView.setPopupTheme (this.mpopuptheme); This.mMenuView.setOnMenuItemClickListener (This.mmenuviewitemclicklistener); This.mMenuView.setMenuCallbacks (This.mactionmenupresentercallback, this.mmenubuildercallback); Toolbar.layoutparams LP = This.generatedefaultlayoutparams (); lp.gravity = 8388613 | This.mbuttongravity &; THIS.MMENUVIEW.SETLAYOUTPARAMS (LP); This.addsystemview (This.mmenuview); } }
It is important here that the function is to create a new toolbar menu bar. Implementing the implementation in Actionmenuview,actionmenuview is no longer the scope of this article, as long as you know Actionmenuview inherits Linearlayoutcompat. In fact, the entire toolbar is a linearlayout layout, just above the custom layout.Parsemenu
private void Parsemenu (xmlpullparser parser, AttributeSet attrs, menu menu) throws Xmlpullparserexception, IOException {supportmenuinflater.menustate menustate = new Supportmenuinflater.menustate (m ENU); int eventtype = Parser.geteventtype (); Boolean lookingforendofunknowntag = false; String unknowntagname = null; String TagName;
<span style= "White-space:pre" ></span>//find <menu> do {if (EventType = = 2) { TagName = Parser.getname (); if (!tagname.equals ("menu")) {throw new RuntimeException ("Expecting menu, got" + tagName); } EventType = Parser.next (); Break } EventType = Parser.next (); } while (EventType! = 1); <span style= "White-space:pre" ></span>//begins to traverse for (Boolean reachedendofmenu = Fals e;!reachedendofmenu; EventType = Parser.next ()) {switch (eventtype) {case 1:throw new RuntimeException (" Unexpected end of document "); Case 2:if (!lookingforendofunknowntag) {tagName = Parser.getname (); if (Tagname.equals ("group")) {Menustate.readgroup (attrs); } else if (Tagname.equals ("item")) {</span>
<span style= "White-space:pre" ></span>//add menu item Menustate.readitem (ATTRS); } else if (Tagname.equals ("menu")) {submenu submenu = Menustate.addsubmenuitem (); This.parsemenu (parser, Attrs, submenu); } else {Lookingforendofunknowntag = true; Unknowntagname = TagName; }} break; Case 3:tagname = Parser.getname (); if (Lookingforendofunknowntag && tagname.equals (unknowntagname)) {Lookingforendofunknowntag = f Alse; Unknowntagname = null; } else if (Tagname.equals ("group")) {Menustate.resetgroup (); } else if (Tagname.equals ("item")) {if (!menustate.hasaddeditem ()) {if (menustate . itemactionprovider! = null && MenuState.itemActionProvider.hasSubMenu ()) {Menustate.addsubmenuitem (); } else {Menustate.additem (); }}}} else if (Tagname.equals ("menu")) {Reachedendofmenu = true; } } } }
when the analysis is finished, display the MenuItem on the menu.
API 5.setOnMenuItemClickListener
Private final Actionmenuview.onmenuitemclicklistener Mmenuviewitemclicklistener = New Actionmenuview.onmenuitemclicklistener () { @Override public boolean Onmenuitemclick (MenuItem item) { IF (Monmenuitemclicklistener! = null) { return Monmenuitemclicklistener.onmenuitemclick (item); } return false; } };
The final implementation is in the Actionmenuview.
Welcome to discuss, purely to stimulate.
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
[Android] Toolbar use in detail (iii)--Source code Analysis