Android Custom View background animation process simple reading <2>

Source: Internet
Author: User

This article is based on the general description of the previous article, I believe that if you read this article, to develop a custom view will be a great help,

First introduce the colorstatelist and statelistdrawable two classes:

Colorstatelist Description: https://developer.android.com/reference/android/content/res/ColorStateList.html

Statelistdrawable Description: https://developer.android.com/reference/android/graphics/drawable/StateListDrawable.html

These two common characteristics are changing the background of the view according to the change of state, colorstatelist is generally the background color update. For example:

XML file saved at Res/color/button_text.xml:

<?xml version= "1.0" encoding= "Utf-8"? ><selector xmlns:android= "http://schemas.android.com/apk/res/ Android ">    <item android:state_pressed=" true "          android:color=" #ffff0000 "/> <!--pressed--    <item android:state_focused= "true"          android:color= "#ff0000ff"/> <!--focused--    <item Android:color= "#ff000000"/> <!--default--></selector>

Then use it in the layout:

<button    android:layout_width= "fill_parent"    android:layout_height= "wrap_content"    android:text= "@ String/button_text "    android:textcolor=" @color/button_text "/>

This place is all Android Native button to complete parsing button_text.xml to update the background/foreground of the parent view, or other adjustments! This is the font that will change color with the click.

If it is a custom view, how to set these actions, take a look at

<1>: Create a new Android Studio project: pumpkindrawable:

Main Class Program:

Package Org.durian.pumpkindrawable;import Android.support.v7.app.appcompatactivity;import Android.os.Bundle; Import Android.widget.imageview;import Org.durian.pumpkindrawable.view.buttoncolordrawable;import    Org.durian.pumpkindrawable.view.pumpkindrawableview;public class Pumpkinmainactivity extends AppCompatActivity {    Private ImageView ImageView1;    Private Buttoncolordrawable bcdrawable;    Private Pumpkindrawableview Pumpkinview;        @Override protected void OnCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate);        Setcontentview (R.layout.activity_pump_kin_main);        imageview1= (ImageView) Findviewbyid (r.id.imagestate);        Bcdrawable=new buttoncolordrawable ();        Imageview1.setbackground (bcdrawable);        Imageview1.setclickable (TRUE);        pumpkinview= (Pumpkindrawableview) Findviewbyid (R.id.pumpkinview);    Pumpkinview.setclickable (TRUE); }}

Corresponding layout file: The inside of the picture to put in a drawable

<?xml version= "1.0" encoding= "Utf-8"? ><linearlayout xmlns:android= "http://schemas.android.com/apk/res/ Android "xmlns:tools=" Http://schemas.android.com/tools "android:layout_width=" Match_parent "android:layout_height = "Match_parent" android:paddingbottom= "@dimen/activity_vertical_margin" android:paddingleft= "@dimen/activity_ Horizontal_margin "android:paddingright=" @dimen/activity_horizontal_margin "android:paddingtop=" @dimen/activity_ Vertical_margin "android:orientation=" vertical "tools:context=" org.durian.pumpkindrawable.PumpKinMainActivity " > <org.durian.pumpkindrawable.view.pumpkindrawableview android:id= "@+id/pumpkinview" Android:clicka Ble= "true" android:layout_width= "250DP" android:layout_height= "250DP"/> <imageview android: Id= "@+id/image" android:layout_width= "wrap_content" android:layout_height= "Wrap_content" android:src= "@drawable/weather"/> <imageview andRoid:id= "@+id/imagestate" android:layout_width= "wrap_content" android:layout_height= "Wrap_content" an droid:src= "@drawable/weather"/></linearlayout>

Then the custom view is as follows:

Package Org.durian.pumpkindrawable.view;import Android.content.res.colorstatelist;import Android.graphics.Canvas; Import Android.graphics.color;import Android.graphics.colorfilter;import Android.graphics.paint;import Android.graphics.pixelformat;import Android.graphics.rectf;import Android.graphics.drawable.animatable;import Android.graphics.drawable.drawable;import android.util.log;/** * Project name:pumpkindrawable * Created by Zhibao.liu o N 2016/4/29. * time:14:58 * Email [email protected] * Action:durian */public class Buttoncolordrawable extends drawable {p    Rivate Paint Mbgpaint;    Private int[] Mnoanimationcolor;    Private Colorstatelist mcolorstatelist;    Private int[][] Btstatus;        Public buttoncolordrawable () {mnoanimationcolor = new int[]{color.blue, Color.green, Color.gray};        Mbgpaint = new Paint (Paint.anti_alias_flag);        Mbgpaint.setcolor (Color.Blue);        Mbgpaint.setstrokewidth (5);        Mbgpaint.setstyle (Paint.Style.FILL); MBGpaint.setantialias (TRUE); The minus sign is false, and the last empty array represents the state beyond the previous two states, this must be put to the end, do not believe you put in the first try to have what consequences btstatus = new int[][]{{-android. R.attr.state_pressed}, {Android.        R.attr.state_pressed}, {}};    Plug the color group corresponding to the previously created state into the queue of this state and color mcolorstatelist = new Colorstatelist (Btstatus, Mnoanimationcolor); }/** * Draw in its bounds (set via setbounds) respecting optional effects such * as alpha (set via Setalpha) a     ND color filter (set via Setcolorfilter). * * @param canvas the canvas to draw into */@Override public void Draw (canvas canvas) {Android.util . LOG.I ("Pumpkin", "Draw ...        ");    Canvas.drawroundrect (New RECTF (GetBounds ()), (Mbgpaint);        After/** * is set to True, drawable cannot accept the state of the control * * @return */@Override public boolean isstateful () {    return true;        } @Override protected Boolean onstatechange (int[] state) {//When the status changes, get the color of the current state, the relationship between this color and the state is the one set inside the structure ANDROID.UTIL.LOG.I ("PumPkin "," Onstatechange ...        ");        int currentcolor = Mcolorstatelist.getcolorforstate (state, Color.White);        Mbgpaint.setcolor (CurrentColor);        Invalidateself ();    return true; }/** * Specify an alpha value for the drawable.     0 means fully transparent, and * 255 means fully opaque. * * @param alpha */@Override public void Setalpha (int alpha) {} @Override public void Setcolorfil    ter (Colorfilter colorfilter) {} @Override public int getopacity () {return pixelformat.translucent; }}


This results in running:

Before clicking:



After clicking:

Yesterday we looked at the source code of the view, as long as the view is clicked will produce KeyEvent, the final call:

protected void drawablestatechanged () {        drawable d = mbackground;        if (d! = null && d.isstateful ()) {            d.setstate (getdrawablestate ());}    }

Then it will be called:

Public boolean setState (final int[] stateset) {        if (! Arrays.equals (Mstateset, Stateset)) {            mstateset = Stateset;            Return Onstatechange (Stateset);        }        return false;    }


So we do buttoncolordrawable when we click on the UI:

Protected Boolean onstatechange (int[] state)

In this method, if you need to update the UI, then:

Invalidateself ();


public void Invalidateself () {        final Callback Callback = Getcallback ();        if (callback! = null) {            callback.invalidatedrawable (this);}    }

In this case, the callback call refreshes the view.
Refresh starts calling the Draw method:

@Override public    void Draw (canvas canvas) {        android.util.log.i ("Pumpkin", "Draw ... ");        Canvas.drawroundrect (New RECTF (GetBounds ()), (+), mbgpaint);    

To achieve the background color change.

Here's how statelistdrawable can achieve the background change: Add the following class to the project above:

Package Org.durian.pumpkindrawable.view;import Android.content.context;import Android.graphics.canvas;import Android.graphics.color;import Android.graphics.paint;import Android.graphics.drawable.drawable;import Android.graphics.drawable.statelistdrawable;import Android.os.asynctask;import Android.os.Handler;import Android.os.message;import Android.util.attributeset;import Android.view.view;import Org.durian.pumpkindrawable.R ;/** * Project name:pumpkindrawable * Created by Zhibao.liu on 2016/4/29. * time:17:09 * Email [email protected] * Action:durian */public class Pumpkindrawableview extends View {Priva    Te Context Mcontext;    Private drawable Mbackground;    Private Boolean mcansizechanged=true;    Private Paint Mpaint;        Public Pumpkindrawableview (Context context) {super (context);    Initview (context); } public Pumpkindrawableview (context context, AttributeSet attrs, int defstyleattr) {Super (context, Attrs, DefS        TYLEATTR); Initview (contEXT); } public Pumpkindrawableview (context context, AttributeSet attrs, int defstyleattr, int defstyleres) {super (con        Text, Attrs, defstyleattr, defstyleres);    Initview (context);        } public Pumpkindrawableview (context context, AttributeSet Attrs) {Super (context, attrs);    Initview (context);        } public void Initview (context context) {Mcontext=context;        Statelistdrawable statelistdrawable = new statelistdrawable (); int pressed = Android.        r.attr.state_pressed; int windowfocused = Android.        r.attr.state_window_focused; int enabled = Android.        r.attr.state_enabled; int statefoucesd = Android.        r.attr.state_focused; Statelistdrawable.addstate (new int[] {pressed, windowfocused}, Mcontext.getresources (). GE        Tdrawable (R.drawable.deskclock));          Statelistdrawable.addstate (new int[] {-pressed, windowfocused}, Mcontext.getresources ()              . Getdrawable (R.drawable.weather));        Mbackground = statelistdrawable;        Mbackground.setcallback (this);        Setbackgrounddrawable (NULL);        Mpaint=new Paint ();    Mpaint.setcolor (Color.yellow);        } @Override protected void drawablestatechanged () {super.drawablestatechanged (); ANDROID.UTIL.LOG.I ("Pumpkin", "drawablestatechanged ...        ");        drawable d = mbackground;        if (d! = null && d.isstateful ()) {d.setstate (Getdrawablestate ());//Drawbackground (); }} @Override protected Boolean verifydrawable (drawable who) {android.util.log.i ("pumpkin", "Verifydraw Able ...        "); return who = = Mbackground | |    Super.verifydrawable (WHO);        } @Override protected void OnDraw (canvas canvas) {super.ondraw (canvas); ANDROID.UTIL.LOG.I ("Pumpkin", "OnDraw ...    ");        } @Override public void draw (canvas canvas) {super.draw (canvas); ANDROID.UTIL.LOG.I ("Pumpkin", "Draw ...        "); if (mbackground! = null) {if (mcansizechanged) {//Set boundary range Mbackground.setbounds                (0, 0, getRight ()-GetLeft (), Getbottom ()-GetTop ());            Mcansizechanged = false; } if ((Getscrollx () | getscrolly ()) = = 0)//offset {mbackground.draw (canvas);//Draw Current            Picture of the state corresponding//canvas.drawcircle (+, radio, mpaint);                } else {canvas.translate (GETSCROLLX (), getscrolly ()); Mbackground.draw (canvas);            Draw the picture of the current state canvas.translate (-GETSCROLLX (),-getscrolly ());    }}}/*int radio=0;    int speechexpand=1;    Boolean drawstatus=false;            public void Drawbackground () {if (drawstatus) {}else{drawstatus=true;        Return        } radio=0; if (task!=null) {if (!task.iscancelled ()) {Task.cancel (true);        }} task=new task ();    Task.execute (); } Private Handler Mhandler=new Handler () {@Override public void Handlemessage (Message msg) {s            Uper.handlemessage (msg);        Invalidate ();    }    };    Private task task;            Private class Task extends asynctask{@Override protected Object doinbackground (object[] params) {                for (int i=0;i<30;i++) {radio + = Speechexpand;                try {thread.sleep (1);                } catch (Interruptedexception e) {e.printstacktrace ();            } mhandler.sendemptymessage (0);        } return null; }    };*/}

Again, after clicking

->drawablestatechanged

if (d! = null && d.isstateful ()) {            d.setstate (getdrawablestate ());//            Drawbackground ();        }
Note that the setstate here triggers a state change, which causes a later view refresh operation, the source is shown above.

->verifydrawable

->ondraw
->draw

Through this process, the view has a background refresh and a running effect:

Before clicking:


After clicking:


It is important to note that all of this is an animation or a color that updates the background in a procedural logical way, and how the background that you normally configure into XML is manipulated in the program,

So the above picture is the background, the viewer can then set the ImageView in the XML src attribute will know.








Android Custom View background animation process simple reading <2>

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.