The use of Guangdong happy to build a dsluntan.com Bezier curve to achieve the sliding effect, the use of property animation to achieve water ripple effect, and then can achieve the above effect
Third, the realization
1. Wrap animation frame First, create animation base class
Pathpoint.java
public class Pathpoint {
public static final int MOVE = 0;public static final int LINE = 1;public static final int CURVE = 2;float mControl0X, mControl0Y;float mControl1X, mControl1Y;public float mX, mY;int mOperation;//line/moveprivate PathPoint(int operation, float x, float y) { this.mOperation = operation; this.mX = x; this.mY = y;}//curveprivate PathPoint(float c0X, float c0Y, float c1X, float c1Y, float x, float y) { this.mControl0X = c0X; this.mControl0Y = c0Y; this.mControl1X = c1X; this.mControl1Y = c1Y; this.mX = x; this.mY = y; this.mOperation = CURVE;}public static PathPoint moveTo(float x, float y) { return new PathPoint(MOVE, x, y);}public static PathPoint lineTo(float x, float y) { return new PathPoint(LINE, x, y);}public static PathPoint curveTo(float c0X, float c0Y, float c1X, float c1Y, float x, float y) { return new PathPoint(c0X, c0Y, c1X, c1Y, x, y);}
}
Create an animated collection class and save the drawing track
Animatorpath
public class Animatorpath {
Record track
Private list<pathpoint> mpoints = new arraylist<> ();
public void moveTo(float x, float y) { mPoints.add(PathPoint.moveTo(x, y));}public void lineTo(float x, float y) { mPoints.add(PathPoint.lineTo(x, y));}public void curveTo(float c0X, float c0Y, float c1X, float c1Y, float x, float y) { mPoints.add(PathPoint.curveTo(c0X, c0Y, c1X, c1Y, x, y));}public Collection<PathPoint> getPoints() { return mPoints;}
}
3. Implement page Layout
<?xml version= "1.0" encoding= "Utf-8"?>
<relativelayout xmlns:android= "Http://schemas.android.com/apk/res/android"
xmlns:app= "Http://schemas.android.com/apk/res-auto"
Android:layout_width= "Match_parent"
android:layout_height= "Match_parent"
android:background= "#ffe8e8e8" >
<imageview android:id= "@+id/album_cover" android:layout_width= "match_parent" android:layout_height= "250DP" Android:background= "#22eeff"/><android.support.v7.widget.toolbar android:id= "@+id/toolbar" Android:layout_ Width= "Match_parent" android:layout_height= "120DP" android:layout_below= "@id/album_cover" Android:layout_marginto p= " -15DP" android:background= "@color/colorprimary" android:elevation= "4DP" android:minheight= "? attr/actionBarSize "android:paddingleft=" 72DP "> <linearlayout android:layout_width=" wrap_content "Android:layout_h eight= "Wrap_content" android:gravity= "center_vertical" android:orientation= "vertical" > <textvie W android:layout_width= "Wrap_content" android:layout_height= "Wrap_content" ANDROID:FONTFA Mily= "Sans-serif" android:text= "Sea Sea" android:textcolor= "#FFF" android:textsize= "30SP"/& Gt <textview Android:layout_width= "Wrap_content" android:layout_height= "Wrap_content" Android:layout_grav Ity= "center_vertical" android:fontfamily= "Sans-serif-light" android:text= "Wangxiao" Android:te Xtcolor= "#9cffffff" android:textsize= "18sp"/> </linearlayout></android.support.v7.widget.toolba R><framelayout android:id= "@+id/fab_container" android:layout_width= "Match_parent" android:layout_height= "1 28DP "android:layout_below=" @id/album_cover "android:layout_margintop=" -30DP "android:elevation=" 10DP "> < ; LinearLayout android:id= "@+id/media_controls_container" android:layout_width= "Wrap_content" android:l ayout_height= "wrap_content" android:layout_gravity= "center" android:orientation= "Horizontal" > < ImageView android:layout_width= "20DP" android:layout_height= "20DP" android:scalex= "0" android:scaley="0" android:src= "@mipmap/play"/> <imageview android:id= "@+id/iv_pause_play" Android:layout_width= "20DP" android:layout_height= "20DP" android:layout_marginleft= "50DP" android:layout_marginright= "50DP" android:scalex= "0" android:scaley= "0" android:src= "@m Ipmap/play "/> <imageview android:layout_width=" 20DP "android:layout_height=" 20DP " android:layout_marginright= "50DP" android:scalex= "0" android:scaley= "0" ANDROID:SR c= "@mipmap/play"/> </LinearLayout> <imagebutton android:id= "@+id/fab" Android:layout_widt H= "56DP" android:layout_height= "56DP" android:layout_gravity= "Top|right" android:layout_marginright= " 72DP "android:background=" @drawable/ripple "android:elevation=" 5DP "android:onclick=" onpabpressed " Android:transitionnAme= "Button_fab"/></framelayout>
</RelativeLayout>
4, get the control, and set the Click event, set some animation constants
Private View Mfab;
Private Framelayout Mfabcontainer;
Private LinearLayout Mcontrolscontainer;
//从什么时候开始执行动画private static final float SCALE_FACTOR = 13f;//持续时间private static final long ANIMATION_DURATION = 300;//贝塞尔曲线滑动到什么时候开始执行动画private static final float MINIMUN_X_DISTANCE = 200;private boolean mRevealFlag;private float mFabSize;
5, set the Click event to Mfab
private void onfabpressed (view view) {
Final float StartX = Mfab.getx ();
Start animation
Animatorpath path = new Animatorpath ();
Path.moveto (0, 0);
Path.curveto (-200, 200,-400, 100,-600, 50);
Path.lineto ( -600,50);
ObjectAnimator anim = ObjectAnimator.ofObject(this, "fabLoc", new PathEvaluator(), path.getPoints().toArray()); anim.setInterpolator(new AccelerateInterpolator());
//Anim.setrepeatcount (Valueanimator.infinite);
//Anim.setrepeatmode (Valueanimator.reverse);
Anim.setduration (animation_duration);
Anim.start ();
Anim.addupdatelistener (New Valueanimator.animatorupdatelistener () {br/> @Override
//to a location in path path is the start of diffusion animation
if (Math.Abs (Startx-mfab.getx ()) > minimun_x_distance) {
if (!mrevealflag) {
ImageButton fab = (ImageButton) mfab;
Fab.setimagedrawable (New bitmapdrawable ());
//Look at the layout inside the Fabcontainer is higher than the toolbar background mfabsize/2 (for the first half fab effect)
Mfabcontainer.sety (mfabcontainer.gety () + MFABSIZE/2);
//fab magnification animation
Mfab.animate ()
. Scalexby (Scale_factor)
. Scaleyby (Scale_factor)
. Setlistener ( Mendreveallistener)
. Setduration (animation_duration);
Mrevealflag = true;
}
}
}
});
}
public void Setfabloc (Pathpoint newloc) {Mfab.settranslationx (newloc.mx); if (Mrevealflag) {//Because the Mfabcontainer inside the layout is MFABSIZE/2 higher than the toolbar background, Fab needs to move up MFABSIZE/2 Mfab.settranslat in order to look smooth Iony (newloc.my-(MFABSIZE/2)); } else {mfab.settranslationy (newloc.my); }}private animatorlisteneradapter Mendreveallistener = new Animatorlisteneradapter () {@Override public void Onanima Tionend (Animator animation) {super.onanimationend (animation); Mfab.setvisibility (view.invisible); Mfabcontainer.setbackgroundcolor (Getresources (). GetColor (r.color.coloraccent)); Reveal animation is complete, then each child control has a scaling animation (in order) for (int i = 0; i < Mcontrolscontainer.getchildcount (); i++) { View v = mcontrolscontainer.getchildat (i); Viewpropertyanimator animate = V.animate (). ScaleX (1). ScaleY (1) . Setduration (Animation_duration); Animate.setstartdelay (i * 50); Animate.start (); } }};
Pathevaluator
public class Pathevaluator implements Typeevaluator<pathpoint> {br/> @Override
T percentage of execution (0~1)
float x, y;
if (endvalue.moperation = = Pathpoint.curve) {
Sanche Besel Curve formula
float oneminust = 1-t;
x = OneminustOneminustOneminuststartvalue.mx +
3OneminustOneminustTendvalue.mcontrol0x +
3OneminustTTendvalue.mcontrol1x +
TTTendvalue.mx;
y = OneminustOneminustOneminuststartvalue.my +
3OneminustOneminustTendvalue.mcontrol0y +
3OneminustTTendvalue.mcontrol1x +
TTTendvalue.my;
} else if (endvalue.moperation = = Pathpoint.line) {
x= starting point +tthe distance from the start and end points
x = startvalue.mx + t(endvalue.mx-startvalue.mx);
y = startvalue.my + t * (endvalue.my-startvalue.my);
} else {
x = endvalue.mx;
y = endvalue.my;
} return PathPoint.moveTo(x, y);}
}
Note: Property animations can either change properties or change a variable or method
Android Cool Guangdong happy very built playing effect