Imitation Android micro-letter 6.0 main interface development implement toggle icon discoloration

Source: Internet
Author: User
Tags drawtext

1. Overview

Learn Android can not but imitate a variety of app interface, since the micro-letter 6.0 After the advent of the micro-letter switch when the color of the tab icon?? Ken Hu Yi Pain? ㄒ Jian and??? Indistinct Shenyang Lai Meshan?

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 that, you can make the icon in the heart of the color of the encounter, 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

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

The code is as follows Copy Code

<?xml version= "1.0" encoding= "Utf-8"?>
<resources>

<attr name= "icon" format= "Reference"/>
<attr name= "Color" format= "Color"/>
<attr name= "Text" format= "string"/>
<attr name= "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

  code is as follows copy code

  <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

The code is as follows Copy Code



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 (). Getdisplaymetrics ());


Private Paint Mtextpaint;


Private Rect Mtextbound = new Rect ();





Public Changecoloriconwithtextview


{


Super (context);


}





/**


* Initialize the custom attribute value


*


* @param context


* @param attrs


*/


Public Changecoloriconwithtextview (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 &lt; n; i++)


{





int attr = A.getindex (i);


Switch (attr)


{


Case R.styleable.changecoloriconview_icon:


Bitmapdrawable drawable = (bitmapdrawable) 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


. Applydimension (TYPEDVALUE.COMPLEX_UNIT_SP, 10,


Getresources (). Getdisplaymetrics ());


Break





}


}





A.recycle ();





Mtextpaint = new Paint ();


Mtextpaint.settextsize (mtextsize);


Mtextpaint.setcolor (0xff555555);


Get text 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:

The code is as follows Copy Code



@Override


protected void onmeasure (int widthmeasurespec, int heightmeasurespec)


{


Super.onmeasure (Widthmeasurespec, Heightmeasurespec);





Get the width of the drawing icon


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 the drawing range of icon


Miconrect = new Rect (left, top, left + bitmapwidth, top + bitmapwidth);





}



3. Draw the icon

There are many steps to drawing an icon, I'll make a list.

1, Compute alpha (default is 0)

2. Draw the original image

3, in the drawing area, draw a solid color block (set Alpha), this step is drawn on the memory of the bitmap

4, set mode, for the memory of the bitmap on the paint

5, Draw our icon, this step is drawn on the memory of the bitmap

6. Draw the original text

7. Draw text after setting alpha and color

8, the memory of the bitmap to draw out

According to the above steps, we can see that our icon is actually drawn two times, why should we draw the original image, because I think it looks better.

3-5 steps, that's the principle we analyzed above.

6-7 steps, is to draw the text, you can see that our text is implemented by setting Alpha

The code is as follows Copy Code



@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 (), Getmeasuredheight (),


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:

The code is as follows Copy Code

     public void Seticonalpha (float alpha)
    {
        This.malpha = Alpha;
        Invalidateview ();
   }

    private void Invalidateview ()
    {
         if (looper.getmainlooper () = = Looper.mylooper ())
        {
  & nbsp         invalidate ();
       } else
        {
    & nbsp;       postinvalidate ();
       }
   }



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


This is really the end, then see usage.



4. Actual Combat

1. layout file

The code is as follows Copy Code



&lt;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" &gt;





&lt;android.support.v4.view.viewpager


Android:id= "@+id/id_viewpager"


Android:layout_width= "Fill_parent"


android:layout_height= "0DP"


android:layout_weight= "1" &gt;


&lt;/android.support.v4.view.ViewPager&gt;





&lt;linearlayout


Android:layout_width= "Fill_parent"


android:layout_height= "60DP"


android:background= "@drawable/TABBG"


android:orientation= "Horizontal" &gt;





&lt;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"/&gt;





&lt;com.zhy.weixin6.ui.changecoloriconwithtextview


Android:id= "@+id/id_indicator_two"


Android:layout_width= "0DP"


android:layout_height= "Fill_parent"


android:layout_weight= "1"


Android:padding= "5DP"


zhy:icon= "@drawable/ic_menu_friendslist"


zhy:text= "@string/tab_contact"


Zhy:text_size= "12SP"/&gt;





&lt;com.zhy.weixin6.ui.changecoloriconwithtextview


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_emoticons"


zhy:text= "@string/tab_find"


Zhy:text_size= "12SP"/&gt;





&lt;com.zhy.weixin6.ui.changecoloriconwithtextview


Android:id= "@+id/id_indicator_four"


Android:layout_width= "0DP"


android:layout_height= "Fill_parent"


android:layout_weight= "1"


Android:padding= "5DP"


zhy:icon= "@drawable/ic_menu_allfriends"


zhy:text= "@string/tab_me"


Zhy:text_size= "12SP"/&gt;


&lt;/LinearLayout&gt;





&lt;/LinearLayout&gt;






2, Mainactivity

The code is as follows Copy Code



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, Onclicklistener


{


Private Viewpager Mviewpager;


Private list&lt;fragment&gt; mtabs = new arraylist&lt;fragment&gt; ();


Private Fragmentpageradapter Madapter;





Private string[] Mtitles = new string[] {"A-fragment!",


"Second fragment!", "Third fragment!", "Fourth Fragment!"};





Private list&lt;changecoloriconwithtextview&gt; Mtabindicator = new arraylist&lt;changecoloriconwithtextview&gt; ();





@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 Tabfragment ();


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) Findviewbyid (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 position, float positionoffset,


int positionoffsetpixels)


{


LOG.E ("TAG", "position =" + position + ", Positionoffset ="


+ Positionoffset);





if (Positionoffset &gt; 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 OnClick (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 &lt; mtabindicator.size (); i++)


{


Mtabindicator.get (i). Seticonalpha (0);


}


}





@Override


public boolean onmenuopened (int featureid, menu menu)


{


if (Featureid = = window.feature_action_bar &amp;&amp; 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, false 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 ("title");


}





TextView TextView = new TextView (getactivity ());


Textview.settextsize (20);


Textview.setbackgroundcolor (Color.parsecolor ("#ffffffff"));


Textview.setgravity (Gravity.center);


Textview.settext (Mtitle);


return textView;


}


}






Well, the whole case is over for us.

You can set a variety of colors in the layout file, 4 different colors can also play it!

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.