自定义View 礼物

package com.example.cll.zidingyiview;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.TypeEvaluator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
import android.graphics.PorterDuff;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;
import android.widget.RelativeLayout;

import java.util.Random;

/**
 * Created by cll on 2017/12/19.
 */

public class CustomView extends RelativeLayout implements View.OnClickListener {
    private Bitmap mBitmap;

    //画笔,路径
    private Paint mPaint;
    private Path mPath;

    //记录屏幕的宽,高
    private int mScreenWidth;
    private int mScreenHeight;

    //记录数据点,控制点(由于是三阶贝塞尔曲线,所以有2个控制点)
    protected Point mStartPoint;
    protected Point mEndPoint;
    protected Point mConOnePoint;
    protected Point mConTwoPoint;

    protected Random mRandom;
    protected int[] mColors = {Color.BLUE, Color.CYAN, Color.GREEN, Color.RED, Color.MAGENTA, Color.YELLOW};


    public CustomView(Context context) {
        super(context);
        initView();
    }

    public CustomView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initView();
    }

    public CustomView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initView();
    }

    /**
     * 进行一些初始化的操作
     */
    private void initView() {
        //初始化画笔,路径
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaint.setStrokeWidth(8);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setColor(Color.BLACK);
        mPath = new Path();
        mRandom = new Random();
        //获取资源图片转化Bitmap(不可修改)
        mBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.icon_star);

        setOnClickListener(this);
    }

    /**
     * 画星星并随机赋予不同的颜色
     *
     * @param color
     * @return
     */
    private Bitmap drawStar(int color) {
        //创建和资源文件Bitmap相同尺寸的Bitmap填充Canvas
        Bitmap outBitmap = Bitmap.createBitmap(mBitmap.getWidth(), mBitmap.getHeight(), Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(outBitmap);
        canvas.drawBitmap(mBitmap, 0, 0, mPaint);
        //利用Graphics中的XferModes对Canvas进行着色
        canvas.drawColor(color, PorterDuff.Mode.SRC_IN);
        canvas.setBitmap(null);
        return outBitmap;
    }

    protected void addStar() {
        Bitmap starBitmap = drawStar(mColors[mRandom.nextInt(mColors.length)]);
        final ImageView imageView = new ImageView(getContext());
        RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(120, 100);
        layoutParams.addRule(CENTER_HORIZONTAL);
        layoutParams.addRule(ALIGN_PARENT_BOTTOM);
        imageView.setImageBitmap(starBitmap);
        addView(imageView, layoutParams);


        Point conOnePoint = this.mConOnePoint;
        Point conTwoPoint = this.mConTwoPoint;
        Point startPoint = this.mStartPoint;
        Point endPoint = this.mEndPoint;


        //设置属性动画
        ValueAnimator valueAnimator = ValueAnimator.ofObject(new StarTypeEvaluator(conOnePoint, conTwoPoint), startPoint,
                endPoint);
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                Point point = (Point) animation.getAnimatedValue();
                imageView.setX(point.x);
                imageView.setY(point.y);
            }
        });

        valueAnimator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
                CustomView.this.removeView(imageView);
            }
        });


        //透明度动画
        ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(imageView, "alpha", 1.0f, 0f);

        //组合动画
        AnimatorSet animatorSet = new AnimatorSet();
        animatorSet.setDuration(4000);
        animatorSet.play(valueAnimator).with(objectAnimator);
        animatorSet.start();


        valueAnimator.start();
    }

    /**
     * 获取屏幕的宽高并设置对应的数据点和控制点
     *
     * @param w
     * @param h
     * @param oldw
     * @param oldh
     */
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        this.mScreenWidth = w;
        this.mScreenHeight = h;
        mStartPoint = new Point(mScreenWidth / 2, mScreenHeight);
        mEndPoint = new Point(mScreenWidth / 2, 0);
        mConOnePoint = new Point(mScreenWidth, mScreenHeight * 3 / 4);
        mConTwoPoint = new Point(0, mScreenHeight / 4);
        //为了调用onDraw方法
        setBackgroundColor(Color.WHITE);

    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
//        mPath.moveTo(mStartPoint.x, mStartPoint.y);
//        mPath.cubicTo(mConOnePoint.x, mConOnePoint.y, mConTwoPoint.x, mConTwoPoint.y, mEndPoint.x, mEndPoint.y);
//        canvas.drawPath(mPath, mPaint);
    }


    class StarTypeEvaluator implements TypeEvaluator {

        //记录控制点
        private Point conOnePoint, conSecondPoint;

        public StarTypeEvaluator(Point conOnePoint, Point conSecondPoint) {
            this.conOnePoint = conOnePoint;
            this.conSecondPoint = conSecondPoint;
        }

        @Override
        public Point evaluate(float t, Point startValue, Point endValue) {

            //利用三阶贝塞尔曲线公式算出中间点坐标
            int x = (int) (startValue.x * Math.pow((1 - t), 3) + 3 * conOnePoint.x * t * Math.pow((1 - t), 2) + 3 *
                    conSecondPoint.x * Math.pow(t, 2) * (1 - t) + endValue.x * Math.pow(t, 3));
            int y = (int) (startValue.y * Math.pow((1 - t), 3) + 3 * conOnePoint.y * t * Math.pow((1 - t), 2) + 3 *
                    conSecondPoint.y * Math.pow(t, 2) * (1 - t) + endValue.y * Math.pow(t, 3));
            return new Point(x, y);
        }
    }

    @Override
    public void onClick(View v) {

//        mStartPoint = new Point(mScreenWidth / 2, mScreenHeight);
//        mEndPoint = new Point((int) (mScreenWidth / 2 + 150 * mRandom.nextFloat()), 0);
//        mConOnePoint = new Point((int) (mScreenWidth * mRandom.nextFloat()), (int) (mScreenHeight * 3 * mRandom.nextFloat() / 4));
//        mConTwoPoint = new Point(0, (int) (mScreenHeight * mRandom.nextFloat() / 4));
//
//        addStar();
    }

    /**
     * 监听onTouch事件,动态生成对应坐标
     * @param event
     * @return
     */
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        mStartPoint = new Point(mScreenWidth / 2, mScreenHeight);
        mEndPoint = new Point((int) (mScreenWidth / 2 + 150 * mRandom.nextFloat()), 0);
        mConOnePoint = new Point((int) (mScreenWidth * mRandom.nextFloat()), (int) (mScreenHeight * 3 * mRandom.nextFloat() / 4));
        mConTwoPoint = new Point(0, (int) (mScreenHeight * mRandom.nextFloat() / 4));

        addStar();
        return true;
    }
}

你可能感兴趣的:(自定义View 礼物)