Android自定义view练手(仿直播点赞)

自定义view中最终要的莫过于贝塞尔曲线的学习和掌握,抽空写了个练手的小玩意。先上效果图
注:本文章不展开介绍贝塞尔曲线(建议先简单认识贝塞尔曲线再食用)

效果图

232DDD151CFF89D0B054B97E136FE1DA.png

废话不多说,直接上代码:

LikeStarView

public class LikeStarView extends View {
    public static final String TAG = "LikeStarView";
    private Bitmap mBitmap;
    private Point mPoint, mStartPoint, mEndPoint;

    public LikeStarView(Context context) {
        this(context, null);
    }

    public LikeStarView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public LikeStarView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    }

    private void init(Context context) {
       //初始化。就加载一个图片。
        Resources resources = context.getResources();
        mBitmap = BitmapFactory.decodeResource(resources, R.drawable.ic_fav);
    }

    @Override
    protected void onDraw(Canvas canvas) {

        canvas.drawBitmap(mBitmap, mPoint.x, mPoint.y, new Paint());

        super.onDraw(canvas);
    }


    public void startanim() {
        if (mStartPoint == null) {
            return;
        }
         //没有做适配,下面500,201等数字可以根据实际传入
        mEndPoint = new Point(mStartPoint.x, mStartPoint.y - 500);//结束的点,起始点就是点击的点

        Random random = new Random();
        int result = random.nextInt(201) - 100; //随机左右偏移控制点位置

        Point controllPoint = new Point(mStartPoint.x + result, mStartPoint.y - 250);//贝塞尔曲线的控制点

        LikeStarEvaluator likeStarEvaluator = new LikeStarEvaluator(controllPoint);
        ValueAnimator animator = ValueAnimator.ofObject(likeStarEvaluator, mStartPoint, mEndPoint);
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                Point point = (Point) animation.getAnimatedValue();
                mPoint.x = point.x;
                mPoint.y = point.y;

                //计算透明度
                setAlpha((float) (point.y - mEndPoint.y) / (float) 500);

                invalidate();
            }
        });

        animator.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {

            }

            @Override
            public void onAnimationEnd(Animator animation) {
//              移除图像
                ViewGroup viewGroup = (ViewGroup) getParent();
                viewGroup.removeView(LikeStarView.this);
            }

            @Override
            public void onAnimationCancel(Animator animation) {

            }

            @Override
            public void onAnimationRepeat(Animator animation) {

            }
        });
        animator.setDuration(2000);
        animator.setInterpolator(new LinearInterpolator());
        animator.start();

    }

//设置初始点
    public void setstartpoint(Point point) {
        this.mStartPoint = point;
        this.mPoint = point;
    }

}

LikeStarEvaluator:

class LikeStarEvaluator implements TypeEvaluator {

   //传入控制点,用于计算路径
    private Point controllPoint;

    public LikeStarEvaluator(Point controllPoint) {
        this.controllPoint = controllPoint;
    }

    @Override
    public Point evaluate(float t, Point startValue, Point endValue) {
//这两个是二阶贝塞尔曲线计算路径上的点公式,这个类通用于用于计算二阶曲线
        int x = (int) ((1 - t) * (1 - t) * startValue.x + 2 * t * (1 - t) * controllPoint.x + t * t * endValue.x);
        int y = (int) ((1 - t) * (1 - t) * startValue.y + 2 * t * (1 - t) * controllPoint.y + t * t * endValue.y);
        return new Point(x, y);//返回获取path上的坐标点
    }
}

LikeStarActivity:(展示view)

public class LikeStarActivity extends AppCompatActivity implements View.OnTouchListener{

    private LinearLayout mTouchView;
    public static final String TAG = "LikeStarActivity";


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_like_star);
        mTouchView = (LinearLayout) findViewById(R.id.touchview);
        mTouchView.setOnTouchListener(this);
    }
  
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        switch (event.getAction()){
            case MotionEvent.ACTION_DOWN:
                LikeStarView likeStarView = new LikeStarView(LikeStarActivity.this);
                //获取起始坐标
                int pointX = (int) event.getRawX();
                int pointY = (int) event.getRawY();
                likeStarView.setstartpoint(new Point(pointX,pointY));
                //添加自定义view
                ViewGroup rootView = (ViewGroup) LikeStarActivity.this.getWindow().getDecorView();
                rootView.addView(likeStarView);
                likeStarView.startanim();
                break;
        }
        return super.onTouchEvent(event);
    }
}

对,就是这么简单。例子比较简单粗糙,只用于学习交流,实际使用还需要适配屏幕尺寸,添加随机颜色爱心等。

Demo地址

你可能感兴趣的:(Android自定义view练手(仿直播点赞))