绘制点在爱心的图片


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());
        }
    }




}


更多相关文章

  1. Android Activity 启动/退出 动画效果
  2. Android 点击赞时弹出+1向上弹出动画
  3. android上开源的酷炫的交互动画和视觉效果
  4. Android Activity实现切换动画的两种方法
  5. android 自定义组件随着手指自动画圆
  6. Android平移动画

随机推荐

  1. Android 之 自定义控件用法介绍
  2. android一些小技巧
  3. 周记:Class4
  4. Android中属性gravity和layout_grativy的
  5. Android ExpandableListView的使用
  6. SQLite 锁机制与事务简介
  7. 【Android】Android控件之Seekbar拖动条
  8. android linearlayout 把控件view置底部(
  9. Android 自定义圆角按钮
  10. android中设置分隔线几种方法