Reference:
Android tweened animation, property animation for shopping cart add animation
Ideas:
- Determine the end point of an animation
- Use two Bezier curves between endpoints to fill the trajectory of points between endpoints
- Set property animation, Valueanimator Interpolator, get coordinates of intermediate points
- Sets the x and Y coordinates of the control that performs the animation to the intermediate point coordinates obtained above
- Turn on property animations
- Action when the animation ends
Difficulties:
Use of Pathmeasure
-GetLength ()
-The understanding of the Boolean Getpostan (float distance, float[] pos, float[] tan)
The knowledge points involved:
- How to use Bezier curves and property animation Interpolator Valueanimator
Iv. Calculating the interpolation coordinates (Bezier curve) of the intermediate animation (in fact, the process of using Bezier curves to finish the end)//start drawing the Bezier curve path Path = new Path (); Move to the starting point (the beginning of the Bezier curve) Path.moveto (StartX, starty); Use two times Sabel curve: Note the larger the first starting coordinate, the greater the transverse distance of the Bezier curve, generally according to the following formula can be Path.quadto ((StartX + ToX)/2, Starty, ToX, ToY); The mpathmeasure is used to calculate the curve length of the Bezier curve and the coordinates of the Bezier intermediate interpolation,//if True,path will form a closed loop Mpathmeasure = new Pathmeasure (path, False ); ★ ¡ï Property Animation Implementation (interpolation between 0 and the length of the Bezier curve to get the distance value of the intermediate process) Valueanimator valueanimator = valueanimator.offloat (0, Mpathmeasure.get Length ()); Valueanimator.setduration (1000); Constant-Speed linear interpolator valueanimator.setinterpolator (New Linearinterpolator ()); Valueanimator.addupdatelistener (New Valueanimator.animatorupdatelistener () {@Override public void O Nanimationupdate (Valueanimator animation) {///when interpolation is calculated, get the middle of each value,//Here This value is the length of the curve in the middle process (below according to this Value to derive the coordinate value of the intermediate point) float value = (float) animation.getanimatedvalUE (); ★★★★★ gets the current point coordinates encapsulated to Mcurrentposition//Boolean Getpostan (float distance, float[] pos, float[] tan): It is important to pass in a distance of distance (0<=distance<=getlength ()) and then calculate the coordinate points and tangents for the current pitch//away, and POS will automatically populate the upper coordinates. Mpathmeasure.getpostan (value, mcurrentposition, null);//mcurrentposition is now the coordinate value of the middle distance point//moving product picture (motion The coordinates of the Goods.settranslationx are set to the coordinates of the intermediate point (mcurrentposition[0]); Goods.settranslationy (mcurrentposition[1]); }});//v. Start the execution of animation Valueanimator.start ();
All code:
Package Cn.c.com.beziercurveanimater;import Android.animation.animator;import Android.animation.ValueAnimator; Import Android.graphics.bitmap;import Android.graphics.bitmapfactory;import Android.graphics.path;import Android.graphics.pathmeasure;import Android.os.bundle;import Android.support.v7.app.appcompatactivity;import Android.support.v7.widget.linearlayoutmanager;import Android.support.v7.widget.recyclerview;import Android.view.layoutinflater;import Android.view.view;import Android.view.viewgroup;import Android.view.animation.linearinterpolator;import Android.widget.imageview;import android.widget.RelativeLayout; Import Android.widget.textview;import Java.util.arraylist;public class Mainactivity extends Appcompatactivity {privat e Recyclerview Mrecyclerview; Private ImageView cart; Private arraylist<bitmap> bitmaplist = new arraylist<> (); Private Relativelayout RL; Private Pathmeasure mpathmeasure; /** * Coordinates of the point of the middle process of the Bezier curve */private float[] McurRentposition = new Float[2]; Private TextView count; private int i = 0; @Override protected void OnCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate); Setcontentview (R.layout.activity_main); Initview (); Initimg (); Myadapter myadapter = new Myadapter (bitmaplist); Mrecyclerview.setadapter (Myadapter); Mrecyclerview.setlayoutmanager (New Linearlayoutmanager (Mainactivity.this)); } private void Initimg () {Bitmaplist.add (Bitmapfactory.decoderesource (Getresources (), r.drawable.coin)); Bitmaplist.add (Bitmapfactory.decoderesource (Getresources (), r.drawable.coin1)); Bitmaplist.add (Bitmapfactory.decoderesource (Getresources (), r.drawable.coin91)); } private void Initview () {Mrecyclerview = (Recyclerview) Findviewbyid (R.id.recyclerview); Cart = (ImageView) Findviewbyid (R.id.cart); RL = (relativelayout) Findviewbyid (R.ID.RL); Count = (TextView) Findviewbyid (R.Id.count); } class Myadapter extends recyclerview.adapter<myvh> {private arraylist<bitmap> bitmaplist; Public Myadapter (arraylist<bitmap> bitmaplist) {this.bitmaplist = bitmaplist; } @Override Public MYVH oncreateviewholder (viewgroup parent, int viewtype) {Layoutinflater Infla ter = Layoutinflater.from (mainactivity.this); View Itemview = Inflater.inflate (R.layout.item, parent, false); MYVH MYVH = new MYVH (Itemview); return MYVH; } @Override public void Onbindviewholder (final MYVH holder, final int position) {Holder.iv.setIm Agebitmap (Bitmaplist.get (position)); Holder.buy.setOnClickListener (New View.onclicklistener () {@Override public void OnClick (Vie W v) {Addcart (HOLDER.IV); } }); } @Override public int getitemcount () {RETurn bitmaplist.size (); }}/** *★★★★★ add the product to the shopping cart animation effect ★★★★★* @param IV */private void Addcart (ImageView iv) {// The theme of action painting---imageview//code new A ImageView, picture resource is a picture of the above ImageView//(this image is an animated image, starting from the starting position, passing a parabola (Bezier curve), moving to the shopping cart) Final ImageView goods = new ImageView (mainactivity.this); Goods.setimagedrawable (Iv.getdrawable ()); Relativelayout.layoutparams params = new Relativelayout.layoutparams (100, 100); Rl.addview (goods, params);//second, the preparation for calculating the coordinates of the start/end point of the animation//Gets the starting point coordinates of the parent layout (coordinates for the point at which the animation starts/ends are calculated) int[] Parentloca tion = new int[2]; Rl.getlocationinwindow (parentlocation); Get the coordinates of the product picture (the coordinates used to calculate the start of the animation) int startloc[] = new INT[2]; Iv.getlocationinwindow (Startloc); Get the shopping cart picture coordinates (used to calculate the coordinates after the end of the animation) int endloc[] = new INT[2]; Cart.getlocationinwindow (endloc);//third, formally start calculating the start/end coordinates of the animation//Start point of the item that started falling: Product start point-parent layout starting point + half of the product picture float star TX = startloc[0]-parEntlocation[0] + iv.getwidth ()/2; float starty = startloc[1]-parentlocation[1] + iv.getheight ()/2; The end point of the commodity falling behind coordinates: Shopping cart start points-parent layout starting point + shopping cart picture of 1/5 float ToX = endloc[0]-parentlocation[0] + cart.getwidth ()/5; float ToY = endloc[1]-parentlocation[1];//Four, calculates the interpolation coordinates (Bezier) of the intermediate animation (which is actually the process of finishing the end with a Bezier curve)//start drawing Bézier curves Pa th path = new path (); Move to the starting point (the beginning of the Bezier curve) Path.moveto (StartX, starty); Use two times Sabel curve: Note the larger the first starting coordinate, the greater the transverse distance of the Bezier curve, generally according to the following formula can be Path.quadto ((StartX + ToX)/2, Starty, ToX, ToY); The mpathmeasure is used to calculate the curve length of the Bezier curve and the coordinates of the Bezier intermediate interpolation,//if True,path will form a closed loop Mpathmeasure = new Pathmeasure (path, False ); ★ ¡ï Property Animation Implementation (interpolation between 0 and the length of the Bezier curve to get the distance value of the intermediate process) Valueanimator valueanimator = valueanimator.offloat (0, Mpathmeasure.get Length ()); Valueanimator.setduration (1000); Constant-Speed linear interpolator valueanimator.setinterpolator (New Linearinterpolator ()); Valueanimator.addupdatelistener (New ValueAnimator.animatorupdatelistener () {@Override public void Onanimationupdate (Valueanimator animation) {//When the interpolation calculation is performed, get each value in the middle,//Here the value is the length of the curve in the middle of the process (below this value to derive the coordinate value of the intermediate point) float value = (Float) Animation.getanimatedvalue (); ★★★★★ gets the current point coordinates encapsulated to Mcurrentposition//Boolean Getpostan (float distance, float[] pos, float[] tan): It is important to pass in a distance of distance (0<=distance<=getlength ()) and then calculate the coordinate points and tangents for the current pitch//away, and POS will automatically populate the upper coordinates. Mpathmeasure.getpostan (value, mcurrentposition, null);//mcurrentposition is now the coordinate value of the middle distance point//moving product picture (motion The coordinates of the Goods.settranslationx are set to the coordinates of the intermediate point (mcurrentposition[0]); Goods.settranslationy (mcurrentposition[1]); }});//v. Start the execution of animation Valueanimator.start ();//VI, after the end of the animation processing Valueanimator.addlistener (new Animato R.animatorlistener () {@Override public void ONanimationstart (Animator animation) {}//When the animation ends: @Override public void Onanim Ationend (Animator animation) {//The number of shopping carts plus 1 i++; Count.settext (string.valueof (i)); Remove the moving picture ImageView from the parent layout rl.removeview (goods); } @Override public void Onanimationcancel (Animator animation) {} @Override public void Onanimationrepeat (Animator animation) {}}); } class MYVH extends Recyclerview.viewholder {private ImageView IV; Private TextView buy; Public MYVH (View Itemview) {super (Itemview); IV = (ImageView) Itemview.findviewbyid (R.ID.IV); Buy = (TextView) Itemview.findviewbyid (r.id.buy); } }}
Full Source:
GitHub
Animate effects (Bezier curves) for adding items to your shopping cart