Android bottom navigation control instance code _android

Source: Internet
Author: User
Tags drawtext getcolor int size

First, to show you the final results

Through the above you can see that figure one is a simple use, figure two, figure three for the combination of Viewpager common use, and can be with viewpager sliding gradient, different point is the selected two pictures, the election of Tu San selected is a picture just made color changes.

Second, demand

We want to do this by introducing controls and binding the data in the XML layout, setting up the listener callback in the code, and configuring it to be very easy to use!

Third, demand analysis

Based on our years of experience in uncertain demand projects, the above requirements are fairly clear. Then we can add the child view control in the LinearLayout, the child view control is our custom tab entry, of course, for LinearLayout to set the weight.

After the requirement is roughly clear, the child view control for each entry is designed, and the child view control is one that can toggle state changes, one and both of which can be toggled (refer to figure I, figure III). So, this view, you can set the text displayed at the bottom, set the color when selected, the color when unchecked, the picture when selected, the picture when unselected, the size of the text, the setting indicates whether there is a point, set the point size, set the indicator point picture, and so on.

Four, Tab entry interface

Through the requirements analysis, we can define the following tab view operation interface:

A careful friend will find out why there are no settings in the interface for selecting a picture and setting a picture when it is not selected, because the attribute is not generic and is defined in different implementations.

Five, TAB entry implementation

The inheritance relationship and description of the class:

The class diagram looks like this:

The main method in Tabviewbase is measurement, the other is the simple implementation of the interface.

@Override 
protected void onmeasure (int widthmeasurespec, int heightmeasurespec) { 
super.onmeasure ( Widthmeasurespec, Heightmeasurespec); 
Gets the wide 
int bitmapwidth = Math.min (Getmeasuredwidth ()-Getpaddingleft () 
-getpaddingright (), Getmeasuredheight ()-Getpaddingtop () 
-Getpaddingbottom ()-mtextbound.height ()); 
int left = Getmeasuredwidth ()/2-BITMAPWIDTH/2; 
int top = (getmeasuredheight ()-mtextbound.height ())/2-BITMAPWIDTH/2; 
Set icon to draw range 
Miconrect = new Rect (left, top, left + bitmapwidth, top + bitmapwidth); 
Sets the range of the indicator point 
int indicatorradius = MINDICATORSIZE/2; 
int tabrealheight = bitmapwidth + mtextbound.height (); 
Mindicatorrect = new Rect (left + tabrealheight* 4/5-Indicatorradius, top, left+tabrealheight* 4/5 + Indicatorradius, top + mindicatorsize); 

In the above code can be seen, measuring the height of the text, with the height of the control minus the height of the text and the width of the control, take a smaller picture size, that is, set the picture to be a square, otherwise it will produce deformation.

Look at the normal two picture toggle Tabview drawing:

@Override 
protected void OnDraw (Canvas Canvas) { 
super.ondraw (Canvas); 
Setuptargetbitmap (canvas); 
Drawindicator (canvas); 
if (null!= mtext) { 
drawtargettext (canvas); 
} 
} 
/** 
* Drawing icon Picture 
* @param canvas * * 
private void Setuptargetbitmap (canvas canvas) { 
Canvas.drawbitmap (isselected mselectediconbitmap:munselectediconbitmap, NULL, miconrect, NULL); 
/** 
* Draw indicator Point 
* @param canvas 
/ 
protected void drawindicator (canvas canvas) { 
if ( Isindicatedisplay) { 
canvas.drawbitmap (mindicatorbitmap, NULL, mindicatorrect, NULL); 
} 
/** 
* Draw Text 
* @param canvas 
/protected void Drawtargettext (canvas canvas) { 
Mtextpaint.setcolor (isselected mselectedcolor:munselectedcolor); 
Canvas.drawtext (Mtext, Miconrect.left + miconrect.width ()/2 
-mtextbound.width ()/2, 
Miconrect.bottom + Mtextbound.height (), mtextpaint); 

Can see very simple, is to draw the icon picture and draw the indicator point, when drawing the picture of the icon to determine whether the current entry is selected, according to whether or not to draw a different picture, at the time of drawing the indicator point to determine whether the display indicator point is set. If there is a bottom text, then long draw the bottom text.
In Viewpager two picture pictures, we will take the effect picture to observe:

There are two modes, that is, with viewpager scrolling icons and normal changes. OK, after understanding we can easily write its drawing, you can draw two pictures, but in the drawing control of its transparency can be, is also very simple.

@Override protected void OnDraw (Canvas Canvas) {Super.ondraw (Canvas); 
int alpha = (int) Math.ceil ((255 * malpha)); 
Drawsourcebitmap (canvas, Alpha); 
Drawtargetbitmap (canvas, Alpha); 
if (null!= mtext) {drawsourcetext (canvas, Alpha); 
Drawtargettext (canvas, Alpha); 
} drawindicator (canvas); /** * Draw Unchecked icon * @param canvas * @param alpha/private void Drawsourcebitmap (canvas canvas, int alpha) {Mpaint. 
Setantialias (TRUE); 
Mpaint.setdither (TRUE); 
Mpaint.setalpha (255-alpha); 
Canvas.drawbitmap (Munselectediconbitmap, NULL, Miconrect, mpaint); /** * Draw the selected icon * @param canvas * @param alpha/private void Drawtargetbitmap (canvas canvas, int alpha) {Mpaint.s 
Etantialias (TRUE); 
Mpaint.setdither (TRUE); 
Mpaint.setalpha (Alpha); 
Canvas.drawbitmap (Mselectediconbitmap, NULL, Miconrect, mpaint); /** * Painting unselected text * @param canvas * @param alpha/private void Drawsourcetext (canvas canvas, int alpha) {Mtextpaint 
. Settextsize (Mtextsize); Mtextpaint.setcolor (MunselEctedcolor); 
Mtextpaint.setalpha (255-alpha); Canvas.drawtext (Mtext, Miconrect.left + miconrect.width ()/2-mtextbound.width ()/2, Miconrect.bottom + mTextBound.he 
Ight (), mtextpaint); /** * Draw selected text * @param canvas * @param alpha/private void Drawtargettext (canvas canvas, int alpha) {Mtextpaint. 
SetColor (Mselectedcolor); 
Mtextpaint.setalpha (Alpha); Canvas.drawtext (Mtext, Miconrect.left + miconrect.width ()/2-mtextbound.width ()/2, Miconrect.bottom + mTextBound.he 
Ight (), mtextpaint); }

The Malpha in your code is the percentage of Viewpager scrolling, and then the selected and unselected icons and text are drawn separately, but the transparency is set differently when you draw them, which results in a gradient effect.

When we viewpager the picture of a single picture, we will take a look at the effect map:

private void Setuptargetbitmap (int alpha) {Mbitmap = Bitmap.createbitmap (Getmeasuredwidth (), Getmeasuredheight (), Conf Ig. 
argb_8888); 
Mcanvas = new Canvas (MBITMAP); 
Mpaint = new Paint (); 
Mpaint.setcolor (Mselectedcolor); 
Mpaint.setantialias (TRUE); 
Mpaint.setdither (TRUE); 
Mpaint.setalpha (Alpha); 
Mcanvas.drawrect (Miconrect, mpaint); 
Mpaint.setxfermode (New Porterduffxfermode (PorterDuff.Mode.DST_IN)); 
Mpaint.setalpha (255); 
Mcanvas.drawbitmap (Miconbitmap, NULL, Miconrect, mpaint); 
private void Drawsourcetext (Canvas Canvas, int alpha) {mtextpaint.settextsize (mtextsize); 
Mtextpaint.setcolor (Munselectedcolor); 
Mtextpaint.setalpha (255-alpha); Canvas.drawtext (Mtext, Miconrect.left + miconrect.width ()/2-mtextbound.width ()/2, Miconrect.bottom + mTextBound.he 
Ight (), mtextpaint); 
private void Drawtargettext (Canvas Canvas, int alpha) {mtextpaint.setcolor (mselectedcolor); 
Mtextpaint.setalpha (Alpha); Canvas.drawtext (Mtext, Miconrect.left + miconrect.width ()/2-Mtextbound.width ()/2, Miconrect.bottom + mtextbound.height (), mtextpaint); }

The drawing process is roughly the same as two pictures, and the difference is that when you draw the picture, paint sets the xfermode to control the gradient of the color.

Custom view of Ok,tab entries The rest is much simpler.

VI. Defining attributes

The next step is to encapsulate the whole control inherited from LinearLayout, first defining the subordinate.

You can see the tabicons for a single picture gradient effect special, tabselectedicons and Tabunselectedicon for two-piece icon switching effect special.

Seven, control writing

Since the three-medium style has a public part, we carry out the accumulation extraction. The class diagram structure is as follows:

1. Constructors Initialize custom properties

To initialize a custom attribute in Tabindicatorbase

private void init (context context, AttributeSet attrs) {setorientation (linearlayout.horizontal); 
Setgravity (Gravity.center); 
Load defaults from the final resources res = getresources (); 
Final int defaultselectedcolor = Res.getcolor (R.color.default_tab_view_selected_color); 
Final int defaultunselectedcolor = Res.getcolor (R.color.default_tab_view_unselected_color); 
Final float defaulttextsize = res.getdimension (r.dimen.default_tab_view_text_size); 
Final float defaulttabpadding = res.getdimension (r.dimen.default_tab_view_padding); 
Final float defaultindicatorsize = res.getdimension (r.dimen.default_tab_view_indicator_size); 
Styleables from XML TypedArray a = Context.obtainstyledattributes (Attrs, r.styleable.tabindicator); The text if (A.hasvalue (r.styleable.tabindicator_tablabels)) {mlabels = A.gettextarray for each tab in the Read layout ( 
R.styleable.tabindicator_tablabels); 
} Mselectedcolor = A.getcolor (R.styleable.tabindicator_tabselectedcolor, Defaultselectedcolor); MunselecteDcolor = A.getcolor (R.styleable.tabindicator_tabunselectedcolor, Defaultunselectedcolor); 
mtextsize = (int) a.getdimension (r.styleable.tabindicator_tabtextsize, defaulttextsize); 
mindicatorsize = (int) a.getdimension (r.styleable.tabindicator_tabindicatorsize, defaultindicatorsize); 
mtabpadding = (int) a.getdimension (r.styleable.tabindicator_tabitempadding, defaulttabpadding); 
Handlestyledattributes (a); 
A.recycle (); 
Initview (); }

Because some properties are not public, the abstract method of Handlestyleattributes (a) is defined here and implemented in subclasses.

2. Initialize View

/** * Initialize control/private void Initview () {layoutparams params = new Layoutparams (0, layoutparams.match_parent, 1); 
params.gravity = Gravity.center; 
int size = Gettabsize (); 
for (int i = 0; i < size; i++) {final int index = i; 
T Tabitemview = Createtabview (); 
Tabitemview.setpadding (mtabpadding, mtabpadding, mtabpadding, mtabpadding); 
icon and text if (null!= mlabels) {tabitemview.settext (Mlabels[index]); 
Tabitemview.settextsize (mtextsize); 
} tabitemview.setselectedcolor (Mselectedcolor); 
Tabitemview.setunselectedcolor (Munselectedcolor); 
Tabitemview.setindicatorsize (mindicatorsize); 
SetProperties (Tabitemview, i); 
This.addview (Tabitemview, params); Tabitemview.settag (index); Checkedtextview sets the index as tag for subsequent changes to the color, picture, etc. mcheckedlist.add (Tabitemview); Adding Checkedtextview to the list makes it easy to manipulate Tabitemview.setonclicklistener (new Onclicklistener () @Override public void OnClick ( View v) {settabsdisplay (index);//Set bottom picture and text display if (null!= mtablistener) {mtablistener.ontabselected (index); 
Tab selected Callback event}}}); 
Initializes the bottom menu selected state, by default the first check if (i = = 0) {tabitemview.setselected (true); 
else {tabitemview.setselected (false); } 
} 
}

Creating tab entries and setting special properties are done in an abstract way to subclasses.

/** 
* Generate Tabview 
* @return 
/protected abstract T Createtabview (); 
/** 
* Set special properties 
* @param t * * 
 

3. Sub-class implementation

Since it's all simpler, let's choose one of the simple two-icon pictures to illustrate:

@Override 
protected void Handlestyledattributes (TypedArray a) { 
//Read layout, icon int for tab use 
Selectediconsresid = A.getresourceid (r.styleable.tabindicator_tabselectedicons, 0); 
TypedArray ta = GetContext (). Getresources (). Obtaintypedarray (SELECTEDICONSRESID); 
int len = Ta.length (); 
Mselecteddrawableids = new Int[len]; 
for (int i = 0; i < len; i++) { 
Mselecteddrawableids[i] = Ta.getresourceid (i, 0); 
} 
int unselectediconsresid = A.getresourceid (r.styleable.tabindicator_tabunselectedicons, 0); 
Ta = GetContext (). Getresources (). Obtaintypedarray (UNSELECTEDICONSRESID); 
Len = Ta.length (); 
Munselecteddrawableids = new Int[len]; 
for (int i = 0; i < len; i++) { 
Munselecteddrawableids[i] = Ta.getresourceid (i, 0); 
} 
Ta.recycle (); 
}

This reads the selected and unchecked icons in the XML configuration

Generate Tabview

@Override 
protected Tabview Createtabview () {return 
new Tabview (GetContext ()); 

Set special properties

@Override 
protected void setproperties (Tabview tabview, int index) { 
Tabview.setselectedicon ( Mselecteddrawableids[index]); 
Tabview.setunselectedicon (Munselecteddrawableids[index]); 

Get the number of entries

@Override 
protected int gettabsize () {return 
mselecteddrawableids.length; 
}

Viii. source code and examples

To provide you with a GitHub address: android-tabindicator
In addition, welcome the star or f**k me on github!

Nine or one lines into the library

If your project is built using Gradle, just add the following line to the dependencies in your Build.gradle file:
Compile ' com.kevin:tabindicator:1.0.1 '

About the small make up to share the Android bottom navigation control instance code is over, hope to help everyone!

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.