The method of making the tab icon discoloration effect in the Android app imitation micro-interface Switch _c language

Source: Internet
Author: User
Tags drawtext

Overview
1. Overview
learn Android without imitating the interface of a variety of apps, since the advent of micro-letter 6.0, I think the micro-letter switch when the color of the tab icon Cock Cock, today I took you to customize the control, take you change color become fly ~ ~
OK, let's look at the effect chart:

Clarity is not very good, we do see ~ ~ There are wood feel this weak burst of color,,, I move my fingers to change your color:

There is no this color comparison demon a little ~ ~ ~ Well ~ below begins to introduce the principle.
2. Principle Introduction
through the above effect chart, you may also guess, our icon is not two pictures, but a picture, and the target color is customizable, who let now talk about personalization.
So how do we do, you can let the icon to the color of the encounter, in fact, the principle in my blog appeared many times, below you will see a familiar picture:

There is no very familiar sense of foot, we actually still use the paint xfermode, this time we are using: mode.dst_in
Dst_in Review what effect, first to draw DST, set mode, and then draw SRC, it shows the intersection area of the plot, and is DST.
Take a closer look at our icons:

In order to facilitate the viewing, I purposely took PS selected the opacity of our icon, we can see that our small robot non-transparent area is the part of the wire frame.
Then, the principle of changing the color of our icons appears:
(1) First draw a color (for example: pink)
(2) Set mode=dst_in
(3) Draw us this cute little robot
Answer me, show what, is not show intersection, what is the intersection? The intersection is the non-transparent area of our little robot, which is the face, except for two eyes;
Okay, so how does it change color?
When I draw a color, can't I set alpha?
To this, we should already understand the principle of the drawing of our icons.
3, Custom icon control
our entire interface Needless to say, is viewpager+fragment, is now concerned about the bottom ~ ~
Next we consider that the bottom of the Tab,tab our layout is linearlayout, the interior four view, through the set weight to achieve the average ~ ~
This view is our custom icon control, which we call: Changecoloriconwithtextview

Key points
next consider what attributes should be posted out
1, custom properties
for a moment, I decided to put the icon, icon color, the text displayed under the icon, the text size of these four properties as custom attributes.
Then the custom attribute goes up:
A, Values/attr.xml

<?xml version= "1.0" encoding= "Utf-8"?> 
<resources> 
 
  <attr name= "icon" format= "Reference" > 
  <attr name= "color" format= "color"/> 
  <attr name= "text" format= "string"/> 
  <attr "Text_size" format= "Dimension"/> 
 
  <declare-styleable name= "Changecoloriconview" > 
    <attr name= " Icon "/> 
    <attr name=" Color "/> 
    <attr name=" text "/> <attr name= 
    " text_size "/> 
  </declare-styleable> 
 
</resources> 

b, using in Layout files

<com.zhy.weixin6.ui.changecoloriconwithtextview 
      android:id= "@+id/id_indicator_one" 
      android:layout_ Width= "0DP" 
      android:layout_height= "fill_parent" 
      android:layout_weight= "1" 
      android:padding= "5DP" 
      zhy:icon= "@drawable/ic_menu_start_conversation" 
      zhy:text= "@string/tab_weixin" 
      zhy:text_size= "12sp "/> 

Pay attention to the namespace of the writing, xmlns:zhy= "http://schemas.android.com/apk/res/application of the package name."
C, in the construction method to obtain

public class Changecoloriconwithtextview extends View {private Bitmap mbitmap; 
  Private Canvas Mcanvas; 
  Private Paint Mpaint; 
  /** * Color/private int mcolor = 0xff45c01a; 
  /** * Transparency 0.0-1.0 * * Private float malpha = 0f; 
  /** * Icon/private Bitmap Miconbitmap; 
  /** * Limit the scope of the drawing icon * * Private Rect miconrect; 
  /** * Icon Bottom text */private String Mtext = "micro-letter"; private int mtextsize = (int) typedvalue.applydimension (typedvalue.complex_unit_sp, Getresources (). Getdisplaym 
  Etrics ()); 
  Private Paint Mtextpaint; 
 
  Private Rect Mtextbound = new Rect (); 
  Public Changecoloriconwithtextview {Super (context); /** * Initializes the custom attribute value * * @param context * @param attrs/public Changecoloriconwithtextview (Cont 
 
    Ext context, AttributeSet attrs) {Super (context, attrs); Gets the icon for the setting TypedArray a = Context.obtainstyledattributes (Attrs, R. styleable. 
 
    Changecoloriconview); 
    int n = a.getindexcount (); 
      for (int i = 0; i < n; i++) {int attr = A.getindex (i); Switch (attr) {case R.styleable.changecoloriconview_icon:bitmapdrawable drawable = (bitmapdrawabl 
        e) a.getdrawable (attr); 
        Miconbitmap = Drawable.getbitmap (); 
      Break 
        Case R.styleable.changecoloriconview_color:mcolor = A.getcolor (attr, 0x45c01a); 
      Break 
        Case r.styleable.changecoloriconview_text:mtext = a.getstring (attr); 
      Break Case r.styleable.changecoloriconview_text_size:mtextsize = (int) a.getdimension (attr, Typedvalue. A 
        Pplydimension (TYPEDVALUE.COMPLEX_UNIT_SP, Getresources (). Getdisplaymetrics ())); 
 
      Break 
 
    } a.recycle (); 
    Mtextpaint = new Paint (); 
    Mtextpaint.settextsize (mtextsize); 
    Mtextpaint.setcolor (0xff555555); Get text to draw range MTEXTPAInt.gettextbounds (mtext, 0, Mtext.length (), mtextbound); 

 }

As you can see, we get the custom attributes in the constructor, and the controls that have the text occupy are in our mtextbound.

2, the selection of the drawing area of the icon
we consider that, with attributes, we need to draw a text, an icon above the text, how do we control the area of the plot?
Our view display area is in the following three situations:

In view of these three kinds of situation, what should be the side length of the icon of my door?
I think the side length should be: the height of the control-the height of the text-the small value of the inner margin and the width of the control-the inner margin; let's examine it carefully;
Well, with the above side-length conclusion, we begin to compute the scope of the icon:

 @Override protected void onmeasure (int widthmeasurespec, int heightmeasurespec) {s 
 
  Uper.onmeasure (Widthmeasurespec, Heightmeasurespec); Gets the wide int bitmapwidth = Math.min (Getmeasuredwidth ()-Getpaddingleft ()-Getpaddingright (), Getmeasuredh 
 
  Eight ()-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); } 

3, Draw icon
draw icon There are many steps, I'll make a list
(1) Compute alpha (default 0)
(2) Draw original image
(3) in the drawing area, draw a solid color block (set Alpha), This step is drawn on the bitmap of Memory
(4) Set mode, which draws our icon for paint
(5) on bitmap in memory, which is drawn on the bitmap of Memory
(6) Draw the original text
(7) Draws the text after setting Alpha and color
(8) to draw the bitmap in memory
According to the above steps, we can see that our icon actually draws two times, why should we draw the original image, because I think it looks better. The
3-5 step, which is the principle we analyzed above
6-7 steps, is to draw the text and see that our text is implemented by setting Alpha

@Override protected void OnDraw (Canvas Canvas) {int alpha = (int) Math.ceil ((255 * malpha)); 
    Canvas.drawbitmap (Miconbitmap, NULL, miconrect, NULL); 
    Setuptargetbitmap (Alpha); 
    Drawsourcetext (canvas, Alpha); 
    Drawtargettext (canvas, Alpha); 
 
  Canvas.drawbitmap (mbitmap, 0, 0, NULL); private void Setuptargetbitmap (int alpha) {Mbitmap = Bitmap.createbitmap (Getmeasuredwidth (), getmeasured 
    Height (), config.argb_8888); 
    Mcanvas = new Canvas (MBITMAP); 
    Mpaint = new Paint (); 
    Mpaint.setcolor (Mcolor); 
    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 (0xff333333); 
    Mtextpaint.setalpha (255-alpha);  Canvas.drawtext (Mtext, Miconrect.left + miconrect.width ()/2-mtextbound.width ()/2, Miconrect.bottom 
  + Mtextbound.height (), mtextpaint); 
    private void Drawtargettext (Canvas Canvas, int alpha) {mtextpaint.setcolor (mcolor); 
    Mtextpaint.setalpha (Alpha);  Canvas.drawtext (Mtext, Miconrect.left + miconrect.width ()/2-mtextbound.width ()/2, Miconrect.bottom 
     
  + Mtextbound.height (), mtextpaint); 

 }

About the calculation of the drawing text area, first is the starting point X:miconrect.left + miconrect.width ()/2-mtextbound.width ()/2 a bit long ha, text Miconrect.left + Miconrect.width ()/2 This position, in the icon horizontal area of the center point, this should not be questioned; the midpoint of the horizontal area of the icon-mtextbound.width ()/2 begins to draw the text, whether it is centered under the icon;
One might ask: How do you know the text width is less than the icon, I have 5 words to do? 5 words how, is still centered display, do not believe you try ~ ~

4, publish the method of setting up the transparency
by this, our icon control has been written, but we have not yet released the method of controlling the icon:

public void Seticonalpha (float alpha) 
{ 
  this.malpha = Alpha; 
  Invalidateview (); 
} 
 
private void Invalidateview () 
{ 
  if (looper.getmainlooper () = = Looper.mylooper ()) 
  { 
    invalidate (); 
  } else 
  { 
    postinvalidate (); 
  } 
} 

We call Seticonalpha, avoid and Setalpha conflict, after the setup is complete, invalidate ~ ~ ~ ~

This is really the end, then see usage.


actual Combat

1. layout file

<linearlayout xmlns:android= "http://schemas.android.com/apk/res/android" xmlns:zhy= "http:// Schemas.android.com/apk/res/com.zhy.weixin6.ui "xmlns:tools=" Http://schemas.android.com/tools "Android:layout_ Width= "Match_parent" android:layout_height= "match_parent" android:orientation= "vertical" > <android.suppo Rt.v4.view.ViewPager android:id= "@+id/id_viewpager" android:layout_width= "Fill_parent" Android:layout_heigh t= "0DP" android:layout_weight= "1" > </android.support.v4.view.ViewPager> <linearlayout Andro Id:layout_width= "Fill_parent" android:layout_height= "60DP" android:background= "@drawable/TABBG" Android:ori entation= "Horizontal" > <com.zhy.weixin6.ui.changecoloriconwithtextview android:id= "@+id/id_indicator_ 
      One "android:layout_width=" 0DP "android:layout_height=" Fill_parent "android:layout_weight=" 1 " android:padding= "5DP" zhy:icon= "@drawable/ic_meNu_start_conversation "zhy:text=" @string/tab_weixin "zhy:text_size=" 12sp "/> <com.zhy.weixin6.u I.changecoloriconwithtextview android:id= "@+id/id_indicator_two" android:layout_width= "0DP" android:l ayout_height= "Fill_parent" android:layout_weight= "1" android:padding= "5DP" zhy:icon= "@drawable/ic_men U_friendslist "zhy:text=" @string/tab_contact "zhy:text_size=" 12sp "/> <com.zhy.weixin6.ui.chang Ecoloriconwithtextview android:id= "@+id/id_indicator_three" android:layout_width= "0DP" android:layout _height= "Fill_parent" android:layout_weight= "1" android:padding= "5DP" zhy:icon= "@drawable/ic_menu_emo Ticons "zhy:text=" @string/tab_find "zhy:text_size=" 12sp "/> <com.zhy.weixin6.ui.changecoloricon Withtextview android:id= "@+id/id_indicator_four" android:layout_width= "0DP" android:layout_height= "fi Ll_parent "Android:layout_weight= "1" android:padding= "5DP" zhy:icon= "@drawable/ic_menu_allfriends" zhy:text= "@string/t 

 Ab_me "zhy:text_size=" 12sp "/> </LinearLayout> </LinearLayout>

2, mainactivity

Package com.zhy.weixin6.ui; 
Import Java.lang.reflect.Field; 
Import Java.lang.reflect.Method; 
Import java.util.ArrayList; 
 
Import java.util.List; 
Import Android.annotation.SuppressLint; 
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.view.Menu; 
Import Android.view.View; 
Import Android.view.View.OnClickListener; 
Import android.view.ViewConfiguration; 
 
Import Android.view.Window; @SuppressLint ("Newapi") public class Mainactivity extends Fragmentactivity implements Onpagechangelistener, Onclickl 
  Istener {private Viewpager mviewpager; 
  Private list<fragment> mtabs = new arraylist<fragment> (); 
 
  Private Fragmentpageradapter Madapter; Private string[] Mtitles = new string[] {"fragment!", "SeconD fragment! "," Third fragment! "," Fourth Fragment! "}; 
 
  Private list<changecoloriconwithtextview> Mtabindicator = new arraylist<changecoloriconwithtextview> (); 
    @Override protected void OnCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate); 
 
    Setcontentview (R.layout.activity_main); 
    Setoverflowshowingalways (); 
    Getactionbar (). setdisplayshowhomeenabled (false); 
 
    Mviewpager = (Viewpager) Findviewbyid (R.id.id_viewpager); 
 
    Initdatas (); 
    Mviewpager.setadapter (Madapter); 
  Mviewpager.setonpagechangelistener (this); private void Initdatas () {for (String title:mtitles) {tabfragment tabfragment = new TABFR 
      Agment (); 
      Bundle args = new Bundle (); 
      Args.putstring ("title", title); 
      Tabfragment.setarguments (args); 
    Mtabs.add (tabfragment); } madapter = new Fragmentpageradapter (Getsupportfragmentmanager ()) {@Override public int getCount () {return mtabs.size (); 
      @Override public Fragment getitem (int arg0) {return mtabs.get (arg0); 
 
    } 
    }; 
 
  Inittabindicator (); 
    @Override public boolean Oncreateoptionsmenu (Menu menu) {getmenuinflater (). Inflate (R.menu.main, menu); 
  return true; private void Inittabindicator () {Changecoloriconwithtextview one = (Changecoloriconwithtextview) findviewb 
    Yid (R.id.id_indicator_one); 
    Changecoloriconwithtextview two = (Changecoloriconwithtextview) Findviewbyid (r.id.id_indicator_two); 
    Changecoloriconwithtextview three = (Changecoloriconwithtextview) Findviewbyid (R.id.id_indicator_three); 
 
    Changecoloriconwithtextview four = (Changecoloriconwithtextview) Findviewbyid (R.id.id_indicator_four); 
    Mtabindicator.add (one); 
    Mtabindicator.add (two); 
    Mtabindicator.add (three); 
 
    Mtabindicator.add (four); 
    One.setonclicklistener (this); Two.setonclicKlistener (this); 
    Three.setonclicklistener (this); 
 
    Four.setonclicklistener (this); 
  One.seticonalpha (1.0f); @Override public void onpageselected (int arg0) {} @Override public void onpagescrolled (int positi On, float positionoffset, int positionoffsetpixels) {//LOG.E ("TAG", "position =" + position + ", Positi 
 
    Onoffset = "//+ Positionoffset); 
      if (Positionoffset > 0) {Changecoloriconwithtextview left = Mtabindicator.get (position); 
 
      Changecoloriconwithtextview right = Mtabindicator.get (position + 1); 
      Left.seticonalpha (1-positionoffset); 
    Right.seticonalpha (Positionoffset); @Override public void onpagescrollstatechanged (int state) {} @Override public void Oncli 
 
    CK (View v) {resetothertabs (); 
      Switch (V.getid ()) {case R.id.id_indicator_one:mtabindicator.get (0). Seticonalpha (1.0f); Mviewpager.setcurrentiteM (0, false); 
    Break 
      Case R.id.id_indicator_two:mtabindicator.get (1). Seticonalpha (1.0f); 
      Mviewpager.setcurrentitem (1, false); 
    Break 
      Case R.id.id_indicator_three:mtabindicator.get (2). Seticonalpha (1.0f); 
      Mviewpager.setcurrentitem (2, false); 
    Break 
      Case R.id.id_indicator_four:mtabindicator.get (3). Seticonalpha (1.0f); 
      Mviewpager.setcurrentitem (3, false); 
 
    Break }/** * Reset other tab/private void Resetothertabs () {for (int i = 0; i < mtabindicator.si Ze (); 
    i++) {mtabindicator.get (i). Seticonalpha (0); @Override public boolean onmenuopened (int featureid, menu menu) {if (Featureid = = Window.feature_a 
        Ction_bar && menu!= null) {if (Menu.getclass (). Getsimplename (). Equals ("Menubuilder")) { try {method M = Menu.getclass (). Getdeclaredmethod ("SetoptionaliconsvisiBle ", boolean.type); 
          M.setaccessible (TRUE); 
        M.invoke (menu, true); 
  catch (Exception e) {}} return super.onmenuopened (Featureid, menu); private void Setoverflowshowingalways () {try {//True if a permanent menu key is present, FAL 
      Se otherwise. 
      viewconfiguration config = viewconfiguration.get (this); 
      Field Menukeyfield = viewconfiguration.class. Getdeclaredfield ("Shaspermanentmenukey"); 
      Menukeyfield.setaccessible (TRUE); 
    Menukeyfield.setboolean (config, false); 
    catch (Exception e) {e.printstacktrace (); 

 } 
  } 
 
}

Activity inside the code although no comment, but very simple ha, is to initialize fragment, get our adapter, and then set to Viewpager;
Inittabindicator We initialize our custom controls, plus the Click event;
The only one that needs to be pointed out is:
We are in the onpagescrolled, dynamic acquisition of position and Positionoffset, and then get about two view, set Positionoffset;
Here expressed ashamed, once in high imitation micro-letter 5.2.1 Main interface architecture contains message notification onpagescrolled wrote a bunch of if else, in the video online, also have students immediately put forward, a line of code to fix ~ ~
So, we have a simple look at the next law, there is no if else's figure ~ ~ ~
There are still two ways to reflect, is to control the Actionbar icon, and click the menu button, the Actionbar menu displayed in the normal area ~ ~

3, Tabfragment

 package com.zhy.weixin6.ui; 
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 {private String mtitle = "Default"; 
      Public tabfragment () {} @Override public View oncreateview (layoutinflater inflater, ViewGroup container, Bundle savedinstancestate) {if (getarguments ()!= null) {mtitle = Getarguments (). getString ("Tit 
    Le "); 
    } TextView TextView = new TextView (getactivity ()); 
    Textview.settextsize (20); 
    Textview.setbackgroundcolor (Color.parsecolor ("#ffffffff")); 
    Textview.setgravity (Gravity.center); 
    Textview.settext (Mtitle); 
  return textView; } 
} 

OK, here we end the whole case ~ ~
You can set a variety of colors in the layout file, 4 different colors can also play it well ~ ~

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.