As long as I click the word "Only", the following will start to rise and bubble up. This is actually a cover-up animation. Prepare three different-colored heart-shaped pictures. In this case, let's start writing it!
Create a new project -- HeartFaom <喎?http: www.bkjia.com kf ware vc " target="_blank" class="keylink"> Alias + DQo8L2Jsb2NrcXVvdGU + DQo8aDIgaWQ9 "bezierevaluator"> BezierEvaluator
PeriscopeLayoutBeiser curve calculation and bubble Realization
Package com. lgl. heartfaom; import java. util. random; import android. animation. animator; import android. animation. animatorListenerAdapter; import android. animation. animatorSet; import android. animation. objectAnimator; import android. animation. valueAnimator; import android. annotation. targetApi; import android. content. context; import android. graphics. pointF; import android. graphics. drawable. drawable; import andro Id. OS. build; import android. util. attributeSet; import android. view. view; import android. view. animation. accelerateDecelerateInterpolator; import android. view. animation. accelerateInterpolator; import android. view. animation. decelerateInterpolator; import android. view. animation. interpolator; import android. view. animation. linearInterpolator; import android. widget. imageView; import android. widget. relativeLayout; Public class PeriscopeLayout extends RelativeLayout {private Interpolator line = new LinearInterpolator (); // linear private Interpolator acc = new acceleration (); // accelerate private Interpolator dce = new DecelerateInterpolator (); // slow down private Interpolator accdec = new AccelerateDecelerateInterpolator (); // first accelerate and then slow down private Interpolator [] interpolators; private int mHeight; private int mWidth; priva Te LayoutParams lp; private Drawable [] drawables; private Random random = new Random (); private int dHeight; private int dWidth; public PeriscopeLayout (Context context) {super (context ); init ();} public PeriscopeLayout (Context context, AttributeSet attrs) {super (context, attrs); init ();} public PeriscopeLayout (Context context, AttributeSet attrs, int defStyleAttr) {super (context, attrs, defSty LeAttr); init () ;}@ TargetApi (Build. public PeriscopeLayout (Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {super (context, attrs, defStyleAttr, defStyleRes); init ();} private void init () {// initialize the drawables = new Drawable [3]; Drawable red = getResources (). getDrawable (R. drawable. pl_red); Drawable yellow = getResources (). getDrawable (R. drawable. pl _ Yellow); Drawable blue = getResources (). getDrawable (R. drawable. pl_blue); drawables [0] = red; drawables [1] = yellow; drawables [2] = blue; // obtain the width and height of the image for later calculation // note that the size of the three images here is the same, so I only took one dHeight = red. getIntrinsicHeight (); dWidth = red. getIntrinsicWidth (); // bottom and horizontal center lp = new LayoutParams (dWidth, dHeight); lp. addRule (CENTER_HORIZONTAL, TRUE); // here, TRUE is not true lp. addRule (ALIGN_PARENT_BOTTOM, TRUE); // initialize the interpolators = new Interpolator [4]; interpolators [0] = line; interpolators [1] = acc; interpolators [2] = dce; interpolators [3] = accdec;} @ Override protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec) {super. onMeasure (widthMeasureSpec, heightMeasureSpec); mWidth = getMeasuredWidth (); mHeight = getMeasuredHeight ();} public void addHeart () {ImageView imageView = New ImageView (getContext (); // select an imageView randomly. setImageDrawable (drawables [random. nextInt (3)]); imageView. setLayoutParams (lp); addView (imageView); Animator set = getAnimator (imageView); set. addListener (new AnimEndListener (imageView); set. start ();} private Animator getAnimator (View target) {AnimatorSet set = getEnterAnimtor (target); ValueAnimator bezierValueAnimator = getBezierValueAnimator (ta Rget); AnimatorSet finalSet = new AnimatorSet (); finalSet. playSequentially (set); finalSet. playSequentially (set, bezierValueAnimator); finalSet. setInterpolator (interpolators [random. nextInt (4)]); finalSet. setTarget (target); return finalSet;} private AnimatorSet getEnterAnimtor (final View target) {ObjectAnimator alpha = ObjectAnimator. ofFloat (target, View. ALPHA, 0.2f, 1f); ObjectAnimator scaleX = O BjectAnimator. ofFloat (target, View. SCALE_X, 0.2f, 1f); ObjectAnimator scaleY = ObjectAnimator. ofFloat (target, View. SCALE_Y, 0.2f, 1f); AnimatorSet enter = new AnimatorSet (); enter. setDuration (500); enter. setInterpolator (new LinearInterpolator (); enter. playTogether (alpha, scaleX, scaleY); enter. setTarget (target); return enter;} private ValueAnimator getBezierValueAnimator (View target) {// initialize a bay Sel calculator--pass BezierEvaluator evaluator = new BezierEvaluator (getPointF (2), getPointF (1 )); // It is best to draw a picture here to understand the input of the start and end ValueAnimator animator = ValueAnimator. ofObject (evaluator, new PointF (mWidth-dWidth)/2, mHeight-dHeight), new PointF (random. nextInt (getWidth (), 0); animator. addUpdateListener (new BezierListenr (target); animator. setTarget (target); animator. setDuration (3000); return animator ;}/*** Get two vertices in the middle ** @ param scale */private PointF getPointF (int scale) {PointF pointF = new PointF (); pointF. x = random. nextInt (mWidth-100); // minus 100 is used to control the activity range of the X axis ~~ // On the Y-axis, to ensure that the second vertex is above the first vertex, I divide Y into the upper half and lower half. In this way, the animation effect is better. You can also use other methods pointF. y = random. nextInt (mHeight-100)/scale; return pointF;} private class BezierListenr implements ValueAnimator. animatorUpdateListener {private View target; public BezierListenr (View target) {this.tar get = target ;}@ Override public void onAnimationUpdate (ValueAnimator animation) {// here, the x y value calculated from the beiser curve is assigned to the view, so that the love will go with the curve. PointF pointF = (PointF) animation. getAnimatedValue (); target. setX (pointF. x); target. setY (pointF. y); // here, by the way, we will make an alpha animation target. setAlpha (1-animation. extends ();} private class AnimEndListener extends AnimatorListenerAdapter {private View target; public AnimEndListener (View target) {this.tar get = target;} @ Override public void onAnimationEnd (Animator animation) {super. onAnimationEnd (animation); // The number of sub-views increases or decreases only because of non-stop add. Therefore, remove removeView (target) after the view animation ends ));}}}
Activity_main.xmlLayout implementation
<Code class = "hljs avrasm"> <relativelayout 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: background = "#000"> </relativelayout> </code> <button android: id = "@ + id/btn_start" android: layout_width = "wrap_content" android: layout_height = "wrap_content" android: layout_cent Erinparent = "true" android: text = "flying! "> <Code class =" hljs avrasm "> <com. lgl. heartfaom. periscopelayout android: id = "@ + id/periscope" android: layout_width = "match_parent" android: layout_height = "match_parent"> </com. lgl. heartfaom. periscopelayout> </code> </button>
MainActivityThen there is how to use it.
Package com. lgl. heartfaom; import android. app. activity; import android. OS. bundle; import android. view. view; import android. view. view. onClickListener; import android. widget. button; public class MainActivity extends Activity {private Button btn_start; // heart bubble private PeriscopeLayout periscopeLayout; @ Override protected void onCreate (Bundle savedInstanceState) {super. onCreate (savedInstanceState); setContentView (R. layout. activity_main); // initialize periscopeLayout = (PeriscopeLayout) findViewById (R. id. perisstart); btn_start = (Button) findViewById (R. id. btn_start); btn_start.setOnClickListener (new OnClickListener () {@ Override public void onClick (View v) {// call periscopeLayout to add bubbles. addHeart ();}});}}
Okay. Now we can run it and try the actual effect.
Nice!