Android apps make today's headline app Viewpager indicator _android

Source: Internet
Author: User
Tags drawtext getcolor

I. Overview
the font of the top Viewpager indicator is discolored, as shown in this effect:

Probably today's headline app, The magic of the place is, when switching Viewpager page, the top indicator changed to the font color changes, personally think it is good.
So the core of the place is to do a support font so gradually stained on it, I think about 32s, scanning some possible solutions, and finally positioned a reliable, below I will take you to begin to realize the journey.
Before implementation, paste our effect chart:
1. Simple use

The effect as above, about the color of the change I added two directions, one is the left direction, one is a direction.
The simple use, may feel is not interesting, below see unifies viewpager to use one example.
2, combined with Viewpager use

You can see when we switch the page, the effect of the indicator above, bang Bang ~ ~ ~
Of course, learned the principle, you can expand, you can do the personality of the progress bar, you can change the font color changes to the background color, you can change the direction of the upper and lower, too much, to pick their own feet to put.

Second, the principle
after watching the effect of the picture, there are wood have any idea ~ ~ ~ Spend a few minutes to think, because the principle is very simple ~ ~
I think about it, the visual drawing half a word estimate not, then work on the scope of the draw, you can draw all, but I control the scope of the display, so the effect:
In fact, it is drawn two times the font, but, respectively, control the rendering range to achieve the effect of gradual discoloration, then for the scope of control, what is the convenient API, it is obvious that some
Canvas has a Cliprect method ~~~ok, the principle analysis is finished ~ ~

Third, implementing
when it comes to implementation, the first step is definitely a custom attribute, and our attributes here need Text,textsize,textorigincolor,textchangecolor, Progress, a general look, should be able to see the role of it, can not see it is okay, combined with the following code. Tip: Our view is called Colortrackview, thanks to the naming of little seven.
1, custom properties, and get
attr.xml

<?xml version= "1.0" encoding= "Utf-8"?> 
<resources> 
 
 <attr name= "text" format= "string"/> 
 <attr name= "text_size" format= "Dimension"/> <attr name= "Text_origin_color" format= "color|" 
 Reference "/> <attr name= text_change_color" format= "color|reference"/> <attr name= " 
 Progress" format= "float"/> 
 <attr name= "direction" > 
  <enum name= "left" value= "0",/> <enum name= 
  " Right "value=" 1 "/> 
 </attr> 
 
 <declare-styleable name=" Colortrackview "> 
  <attr name= "Text"/> 
  <attr name= "text_size"/> <attr name= 
  "Text_origin_color"/> <attr name= " 
  Text_change_color "/> <attr name=" Progress "/> <attr name= 
  " direction "/> 
 </ Declare-styleable> 
 
</resources> 

We then obtain these slag properties in our Colortrackview construction method:

public class Colortrackview extends View {private int mtextstartx; 
 Public enum Direction {left, right; 
  
 private int mdirection = Direction_left; 
 private static final int direction_left = 0; 
  
 private static final int direction_right= 1; 
 public void setdirection (int direction) {mdirection = direction; 
 Private String Mtext = "Zhang Hongyang"; 
 Private Paint Mpaint; 
 
 private int mtextsize = sp2px (30); 
 private int mtextorigincolor = 0xff000000; 
 
 private int mtextchangecolor = 0xffff0000; 
 Private Rect Mtextbound = new Rect (); 
 
 private int mtextwidth; 
 
 private int mrealwidth; 
 
 private float mprogress; 
 Public Colortrackview {Super (context, NULL); 
 
  Public Colortrackview (context, AttributeSet attrs) {Super (context, attrs); 
 
  Mpaint = new Paint (Paint.anti_alias_flag); 
  TypedArray ta = context.obtainstyledattributes (attrs, R.styleable.colortrackview); Mtext = ta.getstring (R.Styleable. 
  Colortrackview_text); 
  Mtextsize = Ta.getdimensionpixelsize (r.styleable.colortrackview_text_size, mtextsize); 
  Mtextorigincolor = Ta.getcolor (R.styleable.colortrackview_text_origin_color, Mtextorigincolor); 
  Mtextchangecolor = Ta.getcolor (R.styleable.colortrackview_text_change_color, Mtextchangecolor); 
   
  mprogress = ta.getfloat (r.styleable.colortrackview_progress, 0); 
   
  Mdirection = Ta.getint (r.styleable.colortrackview_direction, mdirection); 
 
  Ta.recycle (); 
  Mpaint.settextsize (mtextsize); 
 
 Measuretext (); 
  private void Measuretext () {mtextwidth = (int) mpaint.measuretext (mtext); 
 Mpaint.gettextbounds (mtext, 0, Mtext.length (), mtextbound); 

 }


Can see I posted a member variable at the same time, we simply look at the line, are relatively simple.
Get the property, initialize some member variables, then we should go to our measure trip ~ ~

2, Onmeasure

@Override protected void onmeasure (int widthmeasurespec, int heightmeasurespec) {int width = measurewidth (Widthme 
  ASURESPEC); 
  int height = measureheight (heightmeasurespec); 
 
  Setmeasureddimension (width, height); 
  Mrealwidth = Getmeasuredwidth ()-Getpaddingleft ()-getpaddingright (); 
 
 Mtextstartx = MREALWIDTH/2-MTEXTWIDTH/2; 
  private int measureheight (int measurespec) {int mode = Measurespec.getmode (MEASURESPEC); 
  int val = measurespec.getsize (Measurespec); 
  int result = 0; 
   Switch (mode) {case MeasureSpec.EXACTLY:result = val; 
  Break 
   Case MeasureSpec.AT_MOST:case MeasureSpec.UNSPECIFIED:result = Mtextbound.height (); 
  Break result = Mode = = Measurespec.at_most? 
  Math.min (Result, Val): result; 
 return result + getpaddingtop () + Getpaddingbottom (); 
  private int measurewidth (int measurespec) {int mode = Measurespec.getmode (MEASURESPEC); 
  int val = measurespec.getsize (Measurespec); Int result = 0; 
   Switch (mode) {case MeasureSpec.EXACTLY:result = val; 
  Break 
   Case MeasureSpec.AT_MOST:case measurespec.unspecified://result = Mtextbound.width (); 
   result = Mtextwidth; 
  Break result = Mode = = Measurespec.at_most? 
  Math.min (Result, Val): result; 
 return result + getpaddingleft () + getpaddingright (); 

 }

On the measurement, is also a more traditional way of writing, according to the incoming Widthmeasurespec, Heightmeasurespec, the use of measurespec respectively to obtain the model and value, how is exactly all well, if it is at_most, Unspecified then take the space you need to measure yourself, and of course, it's a good idea to note that At_most should not be greater than the value passed in by the parent class.
Here to mention, if lazy, you can choose to inherit TextView, and then measurement will not need to write, TextView the default to help you achieve, but also to take advantage of some of textview properties, but this example is relatively simple, I finally chose to inherit view, Inheritance view has a feeling of everything under control.
After the measurement is complete, it goes without saying that it has been drawn.

3, OnDraw

@Override protected void OnDraw (Canvas Canvas) {Super.ondraw (Canvas); 
   
  int r = (int) (mprogress* mtextwidth +mtextstartx); 
   if (mdirection = = Direction_left) {drawchangeleft (canvas, R); 
  Draworiginleft (canvas, R); 
    }else {draworiginright (canvas, R); 
  Drawchangeright (canvas, R); } private void Drawchangeright (Canvas Canvas, int r) {DrawText (Canvas, Mtextchangecolor, (int) (Mtextstar 
 TX + (1-mprogress) *mtextwidth), mtextstartx+mtextwidth); } private void Draworiginright (Canvas Canvas, int r) {DrawText (Canvas, Mtextorigincolor, MTEXTSTARTX, (int) (Mtext 
 StartX + (1-mprogress) *mtextwidth)); } private void Drawchangeleft (Canvas Canvas, int r) {DrawText (Canvas, Mtextchangecolor, MTEXTSTARTX, (int) (Mtex 
 Tstartx + mprogress * mtextwidth)); } private void Draworiginleft (Canvas Canvas, int r) {DrawText (Canvas, Mtextorigincolor, (int) (MTEXTSTARTX + mPr 
Ogress * mtextwidth), mtextstartx +mtextwidth); } private void DrawText (Canvas Canvas, int color, int startx, int endx) {mpaint.setcolor (color); 
  Canvas.save (Canvas.clip_save_flag); 
  Canvas.cliprect (startx, 0, EndX, Getmeasuredheight ()); 
  Canvas.drawtext (Mtext, Mtextstartx, Getmeasuredheight ()/2 + mtextbound.height ()/2, mpaint); 
 Canvas.restore (); 

 }

The core of the drawing is to use mprogress and direction to compute the scope of the clip, the specific reference code, there is no difficulty. With the scope of the future, nothing but drawtext~~~ here only to speak the main code.

The main method is finished, we should test it.

Four, test

1. Simple test
Layout file

<relativelayout xmlns:android= "http://schemas.android.com/apk/res/android" xmlns:tools= "http:// Schemas.android.com/tools "xmlns:zhy=" Http://schemas.android.com/apk/res-auto "android:layout_width=" Match_ Parent "android:layout_height=" match_parent "> <com.zhy.view.colortrackview android:id=" @+id/id_changeTextC Olorview "android:layout_width=" match_parent "android:layout_height=" Wrap_content "android:layout_centerInParent=" "True" android:background= "#44ff0000" android:padding= "10DP" zhy:progress= "0" zhy:text= "Zhang Hongyang" Zhy:text_chang E_color= "#ffff0000" zhy:text_origin_color= "#ff000000" zhy:text_size= "60sp"/> <linearlayout android:lay Out_width= "Match_parent" android:layout_height= "Wrap_content" android:layout_alignparentbottom= "true" Android:gra vity= "center" android:orientation= "Horizontal" > <button android:id= "@+id/id_left" Android:layout_wi Dth= "Wrap_content" android:layout_height= "Wrap_conteNT "android:onclick=" Startleftchange "android:text=" Startleft "/> <button android:layout_width=" Wra P_content "android:layout_height=" wrap_content "android:layout_torightof=" @id/id_left "android:onClick=" StartR 

 Ightchange "android:text=" Startright "/> </LinearLayout> </RelativeLayout>

Note the namespace of our custom property, which is a colortrackview, and then two buttons to control progress.
Simpleuseactivity:

 package com.zhy.viewpagerIndicator; 
Import Android.animation.ObjectAnimator; 
Import Android.annotation.SuppressLint; 
Import android.app.Activity; 
Import Android.os.Bundle; 
 
Import Android.view.View; 
 
Import Com.zhy.view.ColorTrackView; 
 
 public class Simpleuseactivity extends activity {Colortrackview Mview; 
  @Override protected void OnCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate); 
  Setcontentview (R.layout.activity_simple_main); 
   
 
 Mview = (Colortrackview) Findviewbyid (R.id.id_changetextcolorview); 
  @SuppressLint ("Newapi") public void Startleftchange (view view) {mview.setdirection (0); 
 Objectanimator.offloat (Mview, "Progress", 0, 1). Setduration. Start (); 
  @SuppressLint ("Newapi") public void Startrightchange (view view) {mview.setdirection (1); 
 Objectanimator.offloat (Mview, "Progress", 0, 1). Setduration. Start (); } 
 
} 

Here take the properties of the animation test, did not import 3.0 of the following compatibility package, there is a need to import themselves.
The effect picture is the one above Zhang Hongyang.

2, combined with Viewpager
Layout file:

<linearlayout xmlns:android= "http://schemas.android.com/apk/res/android" xmlns:zhy= "http:// Schemas.android.com/apk/res-auto "xmlns:tools=" Http://schemas.android.com/tools "android:layout_width=" Match_ Parent "android:layout_height=" match_parent "android:orientation=" vertical "> <linearlayout android:layou T_width= "Match_parent" android:layout_height= "50DP" android:orientation= "Horizontal" > <com.zhy.view.colo Rtrackview android:id= "@+id/id_tab_01" android:layout_width= "0DP" android:layout_height= "Match_parent" and roid:layout_weight= "1" zhy:progress= "1" zhy:text= "Introduction" zhy:text_change_color= "#ffff0000" Zhy:text_origin_co Lor= "#ff000000" zhy:text_size= "18sp"/> <com.zhy.view.colortrackview android:id= "@+id/id_tab_02" an Droid:layout_width= "0DP" android:layout_height= "Match_parent" android:layout_weight= "1" zhy:text= "Evaluation" Zhy: Text_change_color= "#ffff0000" zhy:text_origin_color= "#ff000000 "zhy:text_size=" "18sp"/> <com.zhy.view.colortrackview android:id= "@+id/id_tab_03" Android: Layout_width= "0DP" android:layout_height= "Match_parent" android:layout_weight= "1" zhy:text= "related" zhy:text_c  
 
 Hange_color= "#ffff0000" zhy:text_origin_color= "#ff000000" zhy:text_size= "18sp"/> </LinearLayout> <android.support.v4.view.viewpager android:id= "@+id/id_viewpager" android:layout_width= "Match_parent" and roid:layout_height= "0DP" android:layout_weight= "1" > </android.support.v4.view.ViewPager> </linearlayo 

 Ut>

The

3 Colortrackview represents tab, and the following is Viewpager
Viewpageruseactivity:

Package com.zhy.viewpagerIndicator; 
Import java.util.ArrayList; 
 
Import java.util.List; 
Import Android.os.Bundle; 
Import android.support.v4.app.Fragment; 
Import android.support.v4.app.FragmentActivity; 
Import Android.support.v4.app.FragmentPagerAdapter; 
Import Android.support.v4.view.ViewPager; 
Import Android.support.v4.view.ViewPager.OnPageChangeListener; 
 
Import Android.util.Log; 
 
Import Com.zhy.view.ColorTrackView;  public class Viewpageruseactivity extends Fragmentactivity {private string[] Mtitles = new string[] {"Introduction", "Evaluation", "related" 
 }; 
 Private Viewpager Mviewpager; 
 Private Fragmentpageradapter Madapter; 
 Private tabfragment[] mfragments = new Tabfragment[mtitles.length]; 
 
 Private list<colortrackview> mtabs = new arraylist<colortrackview> (); 
  @Override protected void OnCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate); 
 
  Setcontentview (R.layout.activity_vp_main); 
  Initviews (); 
  Initdatas (); 
Initevents (); private void Initevents () {Mviewpager.setonpagechangelistener () {new Onpagechangelistener () {@Override  public void onpageselected (int position) {} @Override public void onpagescrolled (int position, float Positionoffset, int positionoffsetpixels) {if (Positionoffset > 0) {Colortrackview left = 
     Mtabs.get (position); 
      
     Colortrackview right = Mtabs.get (position + 1); 
     Left.setdirection (1); 
     Right.setdirection (0); 
     LOG.E ("TAG", positionoffset+ ""); 
     Left.setprogress (1-positionoffset); 
    Right.setprogress (Positionoffset); 
 
 @Override public void onpagescrollstatechanged (int state) {}});  private void Initdatas () {for (int i = 0; i < mtitles.length; i++) {mfragments[i] = (tabfragment) 
  Tabfragment.newinstance (Mtitles[i]); } madapter = new Fragmentpageradapter (Getsupportfragmentmanager ()) {@Override Public INT GetCount () {return mtitles.length; 
   @Override public Fragment getitem (int position) {return mfragments[position]; 
 
  } 
 
  }; 
  Mviewpager.setadapter (Madapter); 
 Mviewpager.setcurrentitem (0); 
   
  private void Initviews () {Mviewpager = (Viewpager) Findviewbyid (R.id.id_viewpager); 
  Mtabs.add ((Colortrackview) Findviewbyid (r.id.id_tab_01)); 
  Mtabs.add ((Colortrackview) Findviewbyid (r.id.id_tab_02)); 
 Mtabs.add ((Colortrackview) Findviewbyid (r.id.id_tab_03)); 

 } 
 
}

Tabfragment

Package com.zhy.viewpagerIndicator; 
 
Import Java.util.Random; 
Import Android.graphics.Color; 
Import Android.os.Bundle; 
Import android.support.v4.app.Fragment; 
Import android.view.Gravity; 
Import Android.view.LayoutInflater; 
Import Android.view.View; 
Import Android.view.ViewGroup; 
 
Import Android.widget.TextView; 
 public class Tabfragment extends Fragment {public static final String title = "title"; 
 
 Private String Mtitle = "Defaut Value"; 
  @Override public void OnCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate); 
  if (getarguments ()!= null) {mtitle = Getarguments (). getString (TITLE); @Override public View Oncreateview (layoutinflater inflater, ViewGroup container, Bundle savedinstancestate 
  {TextView TV = new TextView (getactivity ()); 
  Tv.settextsize (60); 
  Random r = new Random (); 
  Tv.setbackgroundcolor (Color.argb (R.nextint), R.nextint (255), R.nextint (255), R.nextint (255)); Tv.settext (Mtitle); 
  Tv.setgravity (Gravity.center); 
 
 return TV; 
  public static tabfragment newinstance (String title) {tabfragment tabfragment = new Tabfragment (); 
  Bundle Bundle = new Bundle (); 
  Bundle.putstring (title, title); 
  Tabfragment.setarguments (bundle); 
 return tabfragment; 
 } 
 
}

The

Effect chart is the one that is "combined with Viewpager" above.

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.