绘制点在爱心的图片
package com.example.administrator.testbeisaier.view; import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorMatrix;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import com.example.administrator.testbeisaier.R;
import java.util.Random;
/**
* Created by Administrator on 2017/8/29 0029.
*/
public class FavourHeartView extends View{
Paint mPaint ;
int mHeight,mWidth;
Bitmap bitmap= BitmapFactory.decodeResource(getResources(),R.drawable.anim_heart_border);
public FavourHeartView(Context context) {
super(context);
initPaint();
}
private void initPaint() {
mPaint=new Paint();
Log.e("zjun","initPaint");
mPaint.setAntiAlias(true);
Random random=new Random();
int color= Color.rgb(random.nextInt(255),random.nextInt(255),random.nextInt(255));
mPaint.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.SRC_ATOP));
Log.e("zjun","...");
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
Log.e("zjun","onMeasure");
mWidth=bitmap.getWidth();
mHeight=bitmap.getHeight();
setMeasuredDimension(mWidth,mHeight);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
Log.e("zjun11","w:"+w+" h:"+h);
super.onSizeChanged(w, h, oldw, oldh);
}
@Override
protected void onDraw(Canvas canvas) {
Log.e("zjun","onDraw");
super.onDraw(canvas);
Matrix matrix=new Matrix();
if(bitmap!=null){
canvas.drawBitmap(bitmap,matrix,mPaint);
}
if(bitmap!=null&&!bitmap.isRecycled()){ //回收bitmap;
bitmap.recycle();
}
if(isDrawFinishListenr!=null){
isDrawFinishListenr.isDrawFinish(true);
}
}
IsDrawFinishListenr isDrawFinishListenr;
public interface IsDrawFinishListenr{
void isDrawFinish(boolean isDrawFinish);
}
public void setOnDrawFinishListenr(IsDrawFinishListenr isDrawFinishListenr){
this.isDrawFinishListenr=isDrawFinishListenr;
}
}
添加爱心然后让其执行动画
package com.example.administrator.testbeisaier.view; import android.animation.Animator; import android.animation.ObjectAnimator; import android.animation.TypeEvaluator; import android.animation.ValueAnimator; import android.content.Context; import android.graphics.PointF; import android.util.AttributeSet; import android.util.Log; import android.view.View; import android.view.ViewGroup; import android.widget.RelativeLayout; import com.example.administrator.testbeisaier.R; import java.util.Random; /** * Created by Administrator on 2017/8/29 0029. */ public class FavourLayout extends RelativeLayout { int mWidth,mHeight; private LayoutParams layoutParams; public FavourLayout(Context context) { super(context); } public FavourLayout(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); Log.e("zjun,","onSizeChanged..."); mHeight=h; mWidth=w; Log.e("zjun","w:"+w+" h:"+h); layoutParams =new LayoutParams(w,h); layoutParams.addRule(RelativeLayout.CENTER_HORIZONTAL); layoutParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM); setLayoutParams(layoutParams); } public void addView(){ //在外面的触发事件,例如点赞 Log.e("zjun","addV"); final FavourHeartView favourHeartView= new FavourHeartView(getContext()); favourHeartView.setOnDrawFinishListenr(new FavourHeartView.IsDrawFinishListenr() { @Override public void isDrawFinish(boolean isDrawFinish) { if(isDrawFinish){ addBSEAnimator(favourHeartView); } } }); addView(favourHeartView); addAlpaAnimator(favourHeartView); } private void addAlpaAnimator(final View favourHeartView){ ObjectAnimator animator=ObjectAnimator.ofFloat(favourHeartView,"alpha",1.0f,0.1f).setDuration(2000); animator.start(); } private void addBSEAnimator(final View favourHeartView) { ValueAnimator animator = getBezierValueAnimator(favourHeartView); animator.start(); animator.addListener(new Animator.AnimatorListener() { @Override public void onAnimationStart(Animator animator) { } @Override public void onAnimationEnd(Animator animator) { //因为不停的add 导致子view数量只增不减,所以在view动画结束后remove掉 removeView(favourHeartView); } @Override public void onAnimationCancel(Animator animator) { } @Override public void onAnimationRepeat(Animator animator) { } }); } private ValueAnimator getBezierValueAnimator(View favourHeartView) { //初始化一个贝塞尔计算器- - 传入两个控制点 BezierEvaluator evaluator = new BezierEvaluator(getPointF(2), getPointF(1)); //这里最好画个图 理解一下 传入了起点 和 终点 ValueAnimator animator = ValueAnimator.ofObject(evaluator, new PointF((mWidth - favourHeartView.getWidth()) / 2, mHeight - favourHeartView.getHeight()), new PointF((mWidth - favourHeartView.getWidth()) / 2, 0)); animator.addUpdateListener(new BezierListener(favourHeartView)); animator.setDuration(2000); return animator; } /** * 获取中间的两个 点 * * @param scale */ private PointF getPointF(int scale) { Random random = new Random(); PointF pointF = new PointF(); pointF.x = random.nextInt((mWidth - 100));//减去100 是为了控制 x轴活动范围,看效果 随意~~ //再Y轴上 为了确保第二个点 在第一个点之上,我把Y分成了上下两半 这样动画效果好一些 也可以用其他方法 pointF.y = random.nextInt((mHeight - 100)) / scale; return pointF; } /** *三杰曲线获取点 */ public class BezierEvaluator implements TypeEvaluator { private PointF pointF1; private PointF pointF2; public BezierEvaluator(PointF pointF1,PointF pointF2){ this.pointF1 = pointF1; this.pointF2 = pointF2; } @Override public PointF evaluate(float time, PointF startValue, PointF endValue) { float timeLeft = 1.0f - time; PointF point = new PointF();//结果 point.x = timeLeft * timeLeft * timeLeft * (startValue.x) + 3 * timeLeft * timeLeft * time * (pointF1.x) + 3 * timeLeft * time * time * (pointF2.x) + time * time * time * (endValue.x); point.y = timeLeft * timeLeft * timeLeft * (startValue.y) + 3 * timeLeft * timeLeft * time * (pointF1.y) + 3 * timeLeft * time * time * (pointF2.y) + time * time * time * (endValue.y); return point; } } private class BezierListener implements ValueAnimator.AnimatorUpdateListener { private View target; public BezierListener(View target) { this.target = target; } @Override public void onAnimationUpdate(ValueAnimator animation) { //这里获取到贝塞尔曲线计算出来的的x y值 赋值给view 这样就能让爱心随着曲线走啦 PointF pointF = (PointF) animation.getAnimatedValue(); Log.e("zjun","pointF.x:"+pointF.x+" pointF.y"+pointF.y); target.setX(pointF.x); target.setY(pointF.y); // 这里顺便做一个alpha动画 // target.setAlpha(1 - animation.getAnimatedFraction()); } } }