美文网首页Android自定义控件
Android自定义view练手(仿直播点赞)

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

作者: Singleton丶 | 来源:发表于2017-09-08 20:30 被阅读262次

    自定义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<Point> {
    
       //传入控制点,用于计算路径
        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练手(仿直播点赞)

        本文链接:https://www.haomeiwen.com/subject/lxynjxtx.html