android 模仿qq点赞效果

//自定义view

public class HeartStar extends ViewGroup {
    private List<Drawable> mStarDrawable;
    private int mWidth; //整个控件的宽度
    private int mHeight; //整个控件的高度
   // private Random random = new Random();

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

    public HeartStar(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public HeartStar(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);

    }

    private void init(final Context context) {
        mStarDrawable = new ArrayList<>();
        //初始化图片资源
        mStarDrawable.add(getResources().getDrawable(R.drawable.find_like_img));
        ImageView image_heard = new ImageView(context);
        image_heard.setImageDrawable(mStarDrawable.get(0));
        image_heard.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
        addView(image_heard);
    }
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        measureChildren(widthMeasureSpec, heightMeasureSpec);

        //获取view的宽高测量模式
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);

        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);

        //保存测量高度
        setMeasuredDimension(widthSize, heightSize);
    }
    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        Log.i("wangjitao", "l:" + l + ",t:" + t + ",r:" + r + ",b:" + b);
        View child = getChildAt(0);
        int childW = child.getMeasuredWidth();
        int childH = child.getMeasuredHeight();
        child.layout((mWidth - childW) / 2, (mHeight - childH), (mWidth - childW) / 2 + childW, mHeight);

    }







//属性动画和插补器了解
    //申明属性
    private PointF mStartPoint, mEndPoint;
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        mStartPoint=new PointF();
        mEndPoint=new PointF();
        super.onSizeChanged(w, h, oldw, oldh);

        mWidth = getMeasuredWidth();
        mHeight = getMeasuredHeight();


        // 初始化各个点

        //借用子view控件中的宽高
        View child = getChildAt(0);
        int childW = child.getMeasuredWidth();
        int childH = child.getMeasuredHeight();

        mStartPoint.x = (mWidth - childW) / 2;
        mStartPoint.y = mHeight - childH;
        mEndPoint.x = (mWidth - childW) / 2;
        mEndPoint.y = 0 - childH;
    }

    //自定义TypeEvaluator
    public class BezierTypeEvaluator implements TypeEvaluator<PointF> {

        @Override
        public PointF evaluate(float fraction, PointF startValue, PointF endValue) {
            PointF pointCur = new PointF();
            pointCur.x = mStartPoint.x + fraction * (endValue.x - mStartPoint.x);
            pointCur.y = mStartPoint.y + fraction * (endValue.y - mStartPoint.y);
            return pointCur;
        }
    }

    //向外部提供方法,用于点击事件触发动画发生
    /**
     * 开始动画
     */
    public void startRunning() {
        BezierTypeEvaluator bezierTypeEvaluator = new BezierTypeEvaluator();
        ValueAnimator valueAnimator = ValueAnimator.ofObject(bezierTypeEvaluator, mStartPoint, mEndPoint);
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                PointF pointF = (PointF) animation.getAnimatedValue();
                getChildAt(0).setX(pointF.x);
                getChildAt(0).setY(pointF.y);
            }
        });

        valueAnimator.setDuration(3000);
        valueAnimator.start();
    }

}

activity.xml中:

<com.example.administrator.heart.HeartStar
    android:id="@+id/likestar"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    />

<Button
    android:id="@+id/btn"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="翻滚吧,贝塞尔"
    />

activity点击事件

@Override
public void onClick(View v) {
    switch (v.getId()) {
        case R.id.btn:
            //  likestar = (HeartStar) findViewById(R.id.likestar);
            likestar.startRunning();
            break;
    }
}

 效果图如下:

 

添加贝塞尔曲线

但是我们最终的效果图是每个圆心都是做无规则的曲线上升,这里我们就要使用贝塞尔三阶曲线公式了,这里不了解的童鞋可以去这一篇弄懂,不然后面的计算你是看不懂怎么来的。

 

//在刚才的 evaluate()方法中

private PointF mControllPoint1, mControllPoint2;
private Random random = new Random();  //随机
//自定义TypeEvaluator
public class BezierTypeEvaluator implements TypeEvaluator<PointF> {


    public BezierTypeEvaluator(PointF mControllPointOne, PointF mControllPointTwo) {
        mControllPointOne=new PointF();
        mControllPointTwo=new PointF();
        //设置值
        mControllPointOne.x = random.nextInt(mWidth / 2);
        mControllPointOne.y = random.nextInt(mHeight / 2) + mHeight / 2;

        mControllPointTwo.x = random.nextInt(mWidth / 2) + mWidth / 2;
        mControllPointTwo.y = random.nextInt(mHeight / 2);
        mControllPoint1 = mControllPointOne;
        mControllPoint2 = mControllPointTwo;
    }
    @Override
    public PointF evaluate(float fraction, PointF startValue, PointF endValue) {
        PointF pointCur = new PointF();
        pointCur.x = mStartPoint.x * (1 - fraction) * (1 - fraction) * (1 - fraction) + 3
                * mControllPoint1.x * fraction * (1 - fraction) * (1 - fraction) + 3
                * mControllPoint2.x * (1 - fraction) * fraction * fraction + endValue.x * fraction * fraction * fraction;// 实时计算最新的点X坐标
        pointCur.y = mStartPoint.y * (1 - fraction) * (1 - fraction) * (1 - fraction) + 3
                * mControllPoint1.y * fraction * (1 - fraction) * (1 - fraction) + 3
                * mControllPoint2.y * (1 - fraction) * fraction * fraction + endValue.y * fraction * fraction * fraction;// 实时计算最新的点Y坐标
        return pointCur;
    }
}

//向外部提供方法,用于点击事件触发动画发生
/**
 * 开始动画
 */
public void startRunning() {
    BezierTypeEvaluator bezierTypeEvaluator = new BezierTypeEvaluator(mControllPoint1, mControllPoint2);
    ValueAnimator valueAnimator = ValueAnimator.ofObject(bezierTypeEvaluator, mStartPoint, mEndPoint);
    valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator animation) {
            PointF pointF = (PointF) animation.getAnimatedValue();
            getChildAt(0).setX(pointF.x);
            getChildAt(0).setY(pointF.y);
        }
    });

    valueAnimator.setDuration(3000);
    valueAnimator.start();
}

 再看看运行效果

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值