Recyclerview.itemanimator Ultimate Interpretation (iii)--inherit defaultitemanimator implement custom animation

Source: Internet
Author: User

Defaultitemanimator is a default Recyclerview animation implementation class in the Android OS, and you can use Defaultitemanimator to achieve simple animations if the product requirements are not particularly complex animation requirements. Defaultitemanimator animation of the implementation of the process and principles have been in the last two sections have done a brief introduction, if you have not seen the children's shoes, it is best to drill down the first two sections of the content, to help understand. Attached link address:

1 Recyclerview.itemanimator Ultimate Interpretation (a)--recyclerview source code Analysis

2 Recyclerview.itemanimator Ultimate Interpretation (ii)--simpleitemanimator and Defaultitemanimator source analysis


In this section, we mainly implement a slightly more complex custom animation by inheriting Defaultitemanimator. The effect is shown in the following two images:

As shown in the previous two images: update the background color and text information of the item you clicked on each item you clicked. The first picture is not animated, and the second picture is the effect after adding a custom animation.



The main code is in the custom animation class Mydefaultitemanimator.java, as follows:
Package Material.danny_jiang.com.mydefaultitemanimator;import Android.animation.animator;import Android.animation.animatorlisteneradapter;import Android.animation.animatorset;import Android.animation.argbevaluator;import Android.animation.objectanimator;import Android.graphics.Color;import Android.graphics.drawable.colordrawable;import Android.support.annotation.nonnull;import Android.support.v4.util.arraymap;import Android.support.v7.widget.defaultitemanimator;import Android.support.v7.widget.recyclerview;import Android.util.log;import Android.view.view;import Android.view.animation.accelerateinterpolator;import Android.view.animation.decelerateinterpolator;import Android.widget.linearlayout;import android.widget.textview;import java.util.list;/** * Created by axing on 16/5/25. */public class Mydefaultitemanimator extends Defaultitemanimator {private static final String TAG = "Mydefaultitemanim    Ator "; Defines the acceleration of the animation when it is executed private accelerateinterpolator maccelerateinterpolator = new Accelerateinterpolator ();    Private Decelerateinterpolator Mdecelerateinterpolator = new Decelerateinterpolator ();    Argbevaluator mcolorevaluator = new Argbevaluator (); /** * Defines the map collection of Viewholder that is executing animator * This collection will save the Viewholder object that the user clicked on, in order to determine the viewholder of this itemvie species when the user clicks on an item. Whether the W animation is executing, or if it is executing, stop */private arraymap<recyclerview.viewholder, animatorinfo> manimatormap = new Arraymap&lt    ;> ();     /** * Replication Canreuseupdatedviewholder method and returns True to notify Recyclerview that the Viewholder object can be reused when performing an animation * @param viewholder * @return    */@Override public boolean canreuseupdatedviewholder (Recyclerview.viewholder viewholder) {return true; }/** * Custom Getitemholderinfo method to pass the background color and TextView text information in Viewholder into Colortextinfo * @param viewholder * @pa RAM Info * @return */@NonNull private itemholderinfo getitemholderinfo (Myviewholder viewholder, Colortextin FO info) {//Get the Viewholder object currently in action final myviewholder Myholder = VIewholder;        Gets the Itemview background color in viewholder final int bgColor = ((colordrawable) MyHolder.container.getBackground ()). GetColor ();        Assigns the background color and the text information of the TextView to the color and text variables of the Colortextinfo object info.color = BgColor;        Info.text = (String) myHolder.textView.getText ();    return info;    /** * Gets the background color and text information in the Itemview before the animation is performed by the Viewholder object * Initialize the Colortextinfo object and assign the background color and text information * @return */                                                     @NonNull @Override public Itemholderinfo recordprelayoutinformation (recyclerview.state State, Recyclerview.viewholder viewholder, int changeflags, list<object> payloads) {L        OG.E (TAG, "recordprelayoutinformation:" + viewholder.tostring ()); Colortextinfo info = (colortextinfo) super.recordprelayoutinformation (state, Viewholder, Changeflags, Paylo        ADS);    Return Getitemholderinfo ((myviewholder) Viewholder, info); /** * Gets the background color and text information in the Itemview after the animation is performed by the Viewholder object     * Initialize the Colortextinfo object and assign the background color and text information * @return */@NonNull @Override public itemholderinfo Recordpos Tlayoutinformation (@NonNull recyclerview.state State, @NonNull RECYCL        Erview.viewholder viewholder) {log.e (TAG, "recordpostlayoutinformation:" + viewholder.tostring ());        Colortextinfo info = (colortextinfo) super.recordpostlayoutinformation (state, Viewholder);    Return Getitemholderinfo ((myviewholder) Viewholder, info); }/** * Replication Obtainholderinfo, return custom Itemholderinfo Object * @return */@Override public itemholderinfo obtain        Holderinfo () {LOG.E (TAG, "Obtainholderinfo:");    return new Colortextinfo (); }/** * Custom Itemholderinfo object, holding two variables, sequentially representing the background color and text information for each item */private class Colortextinfo extends Itemholderi        nfo {int color;    String text; }/** * Creates an animated info object that performs Animatechange, internally encapsulating the information required to perform an animation class * Start Alpha Property animation, and start rotation property animation */Private class Animatorinfo {Animator Overallanim;        Objectanimator Fadetoblackanim, Fadefromblackanim, Oldtextrotator, Newtextrotator; Public Animatorinfo (Animator Overallanim, Objectanimator Fadetoblackanim, Objectanimator fadefr Omblackanim, Objectanimator oldtextrotator, Objectanimator newtextrotator) {This.ov            Erallanim = Overallanim;            This.fadetoblackanim = Fadetoblackanim;            This.fadefromblackanim = Fadefromblackanim;            This.oldtextrotator = Oldtextrotator;        This.newtextrotator = Newtextrotator; }}/** * Custom change animation. Fade to black on the container background and then back * up to the new BG Coolor.     Meanwhile, the text rotates, switching along the. * If A new change animation occurs in a item that's currently animating * A change, we stop the previous change and Start the new one where the old * one is left off.     * The real way to perform the change animation: * Through the incoming preinfo and PostInfo, respectively, the background color and text information before and after the animation are set to the Alpha property animation and the Rotation property animation */@Override public bo Olean Animatechange (@NonNull final Recyclerview.viewholder Oldholder, @NonNull final RECYC Lerview.viewholder Newholder, @NonNull itemholderinfo preinfo, @NonNull itemholderinfo Pos        Tinfo) {LOG.E (TAG, "Animatechange:"); if (oldholder! = Newholder) {//When all Recyclerview are displayed for the first time, the old and new Viewholder are unequal return Super.animatechange (o        Ldholder, Newholder, Preinfo, PostInfo);        } final Myviewholder Viewholder = (myviewholder) Newholder;        Gets the background color and text information before and after the animation colortextinfo Oldinfo = (colortextinfo) preinfo;        Colortextinfo Newinfo = (colortextinfo) PostInfo;        int oldcolor = Oldinfo.color;        int newcolor = Newinfo.color;        Final String oldtext = Oldinfo.text;        Final String NewText = Newinfo.text; Gets the view object for which the animation needs to be performed LinearLayout Newcontainer = Viewholder.container;        Final TextView Newtextview = Viewholder.textview; Finds whether the current Newholder corresponding Itemview animation is in execution from the Manimatormap cache, terminates the animation animatorinfo runninginfo = Manimatormap.get (Newholder)        ;        Long prevanimplaytime = 0;        Boolean firsthalf = false; if (runninginfo! = null) {Firsthalf = Runninginfo.oldtextrotator! = NULL && running            Info.oldTextRotator.isRunning ();                    Prevanimplaytime = firsthalf?            RunningInfo.oldTextRotator.getCurrentPlayTime (): RunningInfo.newTextRotator.getCurrentPlayTime ();        RunningInfo.overallAnim.cancel ();        }//Initialize the property animation of the background color gradient objectanimator fadetoblack = null, fadefromblack;            if (Runninginfo = = NULL | | firsthalf) {int startcolor = Oldcolor;            if (runninginfo! = null) {StartColor = (Integer) runningInfo.fadeToBlackAnim.getAnimatedValue ();  }          Fadetoblack = Objectanimator.ofint (Newcontainer, "BackgroundColor", StartColor, Color.Black);            Fadetoblack.setevaluator (Mcolorevaluator);            if (runninginfo! = null) {fadetoblack.setcurrentplaytime (prevanimplaytime); }} fadefromblack = Objectanimator.ofint (Newcontainer, "BackgroundColor", Color.Black, Newcol        OR);        Fadefromblack.setevaluator (Mcolorevaluator);        if (runninginfo! = null &&!firsthalf) {fadefromblack.setcurrentplaytime (prevanimplaytime);        } animatorset Bganim = new Animatorset ();        if (fadetoblack! = null) {bganim.playsequentially (fadetoblack, fadefromblack);        } else {bganim.play (fadefromblack);        }//Initialize animated properties of rotation objectanimator oldtextrotate = null, newtextrotate; if (Runninginfo = = NULL | | firsthalf) {oldtextrotate = Objectanimator.offloat (Newtextview, View.rotation_x, 0, 90);            Oldtextrotate.setinterpolator (Maccelerateinterpolator);            if (runninginfo! = null) {oldtextrotate.setcurrentplaytime (prevanimplaytime);                } oldtextrotate.addlistener (New Animatorlisteneradapter () {Boolean mcanceled = false; @Override public void Onanimationstart (Animator animation) {Newtextview.settext (                OldText);  } @Override public void Onanimationcancel (Animator animation) {mcanceled                = true; } @Override public void Onanimationend (Animator animation) {if (!mcancel                    ed) {//old Animation after the execution, you need to reset the text information newtextview.settext (NewText);        }                }            });        } newtextrotate = Objectanimator.offloat (Newtextview, View.rotation_x,-90, 0);Newtextrotate.setinterpolator (Mdecelerateinterpolator);        if (runninginfo! = null &&!firsthalf) {newtextrotate.setcurrentplaytime (prevanimplaytime);        } animatorset Textanim = new Animatorset ();        if (oldtextrotate! = null) {textanim.playsequentially (oldtextrotate, newtextrotate);        } else {textanim.play (newtextrotate);        } animatorset Changeanim = new Animatorset ();        Changeanim.playtogether (Bganim, Textanim);  Changeanim.addlistener (New Animatorlisteneradapter () {@Override public void Onanimationend (Animator                Animation) {dispatchanimationfinished (Newholder);            Manimatormap.remove (Newholder);        }        });        Changeanim.start (); Animatorinfo runninganiminfo = new Animatorinfo (Changeanim, Fadetoblack, Fadefromblack, Oldtextrotate, NewT        Extrotate);        Manimatormap.put (Newholder, runninganiminfo); REturn true;        } @Override public void Endanimation (Recyclerview.viewholder item) {super.endanimation (item);            if (!manimatormap.isempty ()) {final int numrunning = Manimatormap.size (); for (int i = numrunning; I >= 0; i--) {if (item = = Manimatormap.keyat (i)) {Manimato                Rmap.valueat (i). Overallanim.cancel (); }}}} @Override public boolean isrunning () {return super.isrunning () | |!manimatormap    . IsEmpty ();        } @Override public void Endanimations () {super.endanimations ();            if (!manimatormap.isempty ()) {final int numrunning = Manimatormap.size ();            for (int i = numrunning; I >= 0; i--) {manimatormap.valueat (i). Overallanim.cancel (); }        }    }}

The meaning of each piece of code has been added to the code of the corresponding comments, please endure loneliness, carefully review ^_^ custom Itemanimator implementation, the rest is to initialize the Recyclerview, and pass the custom Itemanimator object to Recyclerview through the Setitemanimator method.
The relevant code in Mainactivity.java is as follows:
Recyclerview = ((Recyclerview) Findviewbyid (R.id.recyclerview)); Recyclerview.setlayoutmanager (new Linearlayoutmanager (this)); Recyclerview.setadapter (New Recycleradapter (this, recyclerview)); Recyclerview.setitemanimator (New Mydefaultitemanimator ());


The Recycleradapter.java code is as follows:
@Override public void Onbindviewholder (myviewholder holder, int position) {final Myviewholder Myholder = (myvie        Wholder) holder;        int color = mcolors.get (position);        MyHolder.container.setBackgroundColor (color);    MyHolder.textView.setText ("#" + integer.tohexstring (color));    } @Override public int getitemcount () {return mcolors.size (); }private View.onclicklistener mitemaction = new View.onclicklistener () {@Override public void OnClick (View        V) {Changeitem (v);    }    }; @Override public Myviewholder Oncreateviewholder (viewgroup parent, int viewtype) {View container = mainactivity        . Getlayoutinflater (). Inflate (R.layout.item_layout, parent, false);        Container.setonclicklistener (mitemaction);    return new Myviewholder (container);        } private int Generatecolor () {int red = ((int) (Math.random () * 200));        int green = ((int) (Math.random () * 200)); int blue = ((int) (MAth.random () * 200));    Return Color.rgb (red, green, blue);        }private void Generatedata () {for (int i = 0; i <; ++i) {Mcolors.add (Generatecolor ());        }}private void Changeitem (view view) {int position = mrecyclerview.getchildadapterposition (view);            if (position! = recyclerview.no_position) {int color = Generatecolor ();            Mcolors.set (position, color);        Notifyitemchanged (position); }    }


The Myviewholder.java code is as follows:
Package Material.danny_jiang.com.mydefaultitemanimator;import Android.support.v7.widget.recyclerview;import Android.view.view;import android.widget.linearlayout;import android.widget.textview;/** * Created by axing on 16/5/25. */class Myviewholder extends Recyclerview.viewholder {public    TextView TextView;    public LinearLayout container;    Public Myviewholder (View v) {        super (v);        container = (linearlayout) v;        TextView = (TextView) V.findviewbyid (R.id.textview);    }    @Override public    String toString () {        return super.tostring () + "\" "+ textview.gettext () +" \ "";    }}


Recyclerview.itemanimator Ultimate Interpretation (iii)--inherit defaultitemanimator implement custom animation

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.