点赞动画---图标

作者: zsgnaw | 来源:发表于2017-11-27 16:21 被阅读330次
ezgif-4-592fb3675c.gif
public class IconAnimatorView extends View implements View.OnClickListener {

    private static final String TAG = "IconAnimatorView";

    private static final int QUICK_CLIKC_INTERVAL = 500;
    private static final int BITMAP_SELECTED = R.mipmap.ic_messages_like_selected;
    private static final int BITMAP_UNSELECTED = R.mipmap.ic_messages_like_unselected;
    //缩放最小值
    private static final float SCALE_MIN = 0.8f;
    //缩放最大值
    private static final float SCALE_MAX = 1f;
    //缩放动画的时间
    private static final int SCALE_DURING = 150;
    //圆圈扩散动画的时间
    private static final int CICLE_DURING = 300;
    //扩散圆圈大于图标的
    private static final int CICLE_BIGGER = 2;
    //扩散圆圈的颜色
    private static final int CICLE_COLOR = 0x88e24d3d;

    private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); //普通画笔
    private Bitmap mBitmapSelected; //选中图标
    private Bitmap mBitmapUnselected; //未选中图标
    private Matrix mMatrixSelected = new Matrix(); //
    private Matrix mMatrixUnSelected = new Matrix(); //
    private PointF mPoint = new PointF(); //图标位置
    private Path mPathCicle = new Path(); //扩散光圈
    private int mMaxRadio; //光圈最大直径
    private Paint mCirclePaint = new Paint(Paint.ANTI_ALIAS_FLAG); //圆圈画笔
    private PointF mPointCenter = new PointF(); //图圈圆心位置

    private boolean mSelected;
    private long lastClickTime;

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

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

    public IconAnimatorView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.IconAnimatorView);
        init(typedArray);
        typedArray.recycle();
    }

    private void init(TypedArray typedArray) {
        mSelected = typedArray.getBoolean(R.styleable.IconAnimatorView_ia_selected, false);
        //选中、未选中图标
        int select = typedArray.getResourceId(R.styleable.IconAnimatorView_ia_icon_selected, BITMAP_SELECTED);
        int unselect = typedArray.getResourceId(R.styleable.IconAnimatorView_ia_icon_unselected, BITMAP_UNSELECTED);
        mBitmapSelected = BitmapFactory.decodeResource(getResources(), select);
        mBitmapUnselected = BitmapFactory.decodeResource(getResources(), unselect);

        int cicleColor = typedArray.getColor(R.styleable.IconAnimatorView_ia_cicle_color, CICLE_COLOR);
        mCirclePaint.setColor(cicleColor);
        mCirclePaint.setStyle(Paint.Style.STROKE);
        mCirclePaint.setStrokeWidth(3);

        int w = mBitmapSelected.getWidth() / 2;
        int h = mBitmapSelected.getHeight() / 2;
        mMaxRadio = (int) (Math.sqrt(w * w + h * h) + CICLE_BIGGER);
        mPointCenter.set(getPaddingLeft() + mMaxRadio, getPaddingTop() + mMaxRadio);
        mPoint.set(mPointCenter.x - mBitmapSelected.getWidth() / 2, mPointCenter.y - mBitmapSelected.getHeight() / 2);

        translateMatrix(mMatrixSelected);
        translateMatrix(mMatrixUnSelected);

        setOnClickListener(this);
    }

    private void translateMatrix(Matrix matrix) {
        matrix.setTranslate(mPoint.x, mPoint.y);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (mSelected) {
            canvas.drawPath(mPathCicle, mCirclePaint);
            canvas.drawBitmap(mBitmapSelected, mMatrixSelected, mPaint);
        } else {
            canvas.drawBitmap(mBitmapUnselected, mMatrixUnSelected, mPaint);
        }
    }

    @Override
    public void onClick(View view) {

        if (System.currentTimeMillis() - lastClickTime < QUICK_CLIKC_INTERVAL){
            Log.e(TAG,"短时间快速无效点击");
            lastClickTime = System.currentTimeMillis();
            return;
        }

        lastClickTime = System.currentTimeMillis();

        if (mSelected) {
            // 点击切换为未选中
            ObjectAnimator animator = ObjectAnimator.ofFloat(this, "iconSelected", SCALE_MAX, SCALE_MIN);
            animator.setDuration(SCALE_DURING);

            ObjectAnimator animator1 = ObjectAnimator.ofFloat(this, "iconUnSelected", SCALE_MIN, SCALE_MAX);
            animator1.setDuration(SCALE_DURING);

            AnimatorSet animatorSet = new AnimatorSet();
            animatorSet.play(animator1).after(animator);
            animatorSet.start();
        } else {
            ObjectAnimator animator = ObjectAnimator.ofFloat(this, "iconSelected", SCALE_MIN, SCALE_MAX);
            animator.setDuration(SCALE_DURING);

            ObjectAnimator animator1 = ObjectAnimator.ofFloat(this, "iconUnSelected", SCALE_MAX, SCALE_MIN);
            animator1.setDuration(SCALE_DURING);

            ObjectAnimator animator2 = ObjectAnimator.ofFloat(this, "cicleScale", 0, mMaxRadio);
            animator2.setDuration(CICLE_DURING);

            AnimatorSet animatorSet = new AnimatorSet();
            animatorSet.play(animator).after(animator1);
            animatorSet.play(animator).with(animator2);
            animatorSet.start();
        }
    }

    /**
     * 选中图标缩放动画
     * @param scale
     */
    private void setIconSelected(float scale) {

        translateMatrix(mMatrixSelected);
        mMatrixSelected.postScale(scale, scale, mPointCenter.x, mPointCenter.y);
        mSelected = true;
        invalidate();
    }

    /**
     * 未选中图标缩放动画
     *
     * @param scale
     */
    private void setIconUnSelected(float scale) {

        translateMatrix(mMatrixUnSelected);
        mMatrixUnSelected.postScale(scale, scale, mPointCenter.x, mPointCenter.y);
        mSelected = false;
        invalidate();
    }

    /**
     * 圆圈扩散动画
     *
     * @param radio
     */
    private void setCicleScale(float radio) {
        mPathCicle.reset();
        if (radio < mMaxRadio) {
            mPathCicle.addCircle(mPointCenter.x, mPointCenter.y, radio, Path.Direction.CW);
        }
        mSelected = true;
        invalidate();
    }

    // 计算尺寸
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        int width = MeasureSpec.getSize(widthMeasureSpec);
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int height = MeasureSpec.getSize(heightMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);

        //最大宽度 = 左间距 + 扩散圈直径 + 右间距
        int wrapWidth = getPaddingLeft() + mMaxRadio * 2 + getPaddingRight();
        //最大高度 = 上间距 + 扩散圈直径 + 下间距
        int wrapHeight = getPaddingTop() + mMaxRadio * 2 + getPaddingBottom();

        //计算wrap_content时的情况
        if (widthMode == MeasureSpec.AT_MOST && heightMode == MeasureSpec.AT_MOST) {
            setMeasuredDimension(wrapWidth, wrapHeight);
        } else if (widthMode == MeasureSpec.AT_MOST) {
            setMeasuredDimension(wrapWidth, height);
        } else if (heightMode == MeasureSpec.AT_MOST) {
            setMeasuredDimension(width, wrapHeight);
        }
    }

    /**
     * 设置选中状态
     * @param selected
     * @param isAnimator 是否有动画
     */
    public void setIconSelected(boolean selected,boolean isAnimator){
        if (selected && mSelected){
            return;
        }

        if (isAnimator){
            onClick(this);
        } else {
            mSelected = selected;
            invalidate();
        }
    }

    public boolean getIconSelected(){
        return mSelected;
    }

}

主要是学习简单的自定义View跟动画。

相关文章

  • 点赞动画---图标

    主要是学习简单的自定义View跟动画。

  • React-native 文章点赞、取消赞

    点赞操作:客户端只处理点赞的状态和取消点赞的状态,具体就是点赞后图标变红,下面的点赞数+1,取消点赞时,图标去红,...

  • ios 点赞动画

    模仿的qq空间的点赞。qq的是从未点赞状态到点赞是有动画。从点赞状态到未点赞是没有动画。 写的butten的分类。...

  • 点赞动画

    先上效果图 调用也简单,在布局(xml文件)里添加 然后bubble.addHeart()

  • 腾讯网易开战了-吃鸡游戏哪家好

    一觉醒来,打开QQ,给朋友点赞,点赞动画出现的时候,我发现不对劲,我平时都是默认的点赞,点赞动画只会逢年过节的时候...

  • 点赞,收益相关

    1、点赞:长按点赞图标,选择小赞、大赞、超赞,可以帮助我们适当分配能量使用。 每日能量保持50多一点,恢复较快。不...

  • 2018-09-11

    产投集团APP-智慧党建系统1、优化资讯详情评论列表是否点赞图标2、新增点赞评论图标3、优化组织模块页面加载优化4...

  • Swift---点赞/取消点赞头像动画

    需求: 点赞/取消点赞后,头像要有移动动画。 思路:点赞:已有头像右移,新增头像渐变出现 取消点赞: 个人已点赞可...

  • UI更改

    1.logo 2.动态图标 3.三个图标 3.1 点赞图标 4.主色调其他,你看着办

  • Adapter只刷新某一个子View

    案例:盆友圈点赞时候,只刷新当前item里面的点赞图标,别的不刷新。 方法:

网友评论

    本文标题:点赞动画---图标

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