前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android TextView 仿动控件

Android TextView 仿动控件

作者头像
萬物並作吾以觀復
发布2021-11-24 14:03:29
5500
发布2021-11-24 14:03:29
举报
文章被收录于专栏:指尖下的Android指尖下的Android

看到一些应用中的点赞觉得挺有意思,具体效果大概就是这个样子

50buq-l34h1.gif

然后我仿写了下,效果差不多,代码比较简单就不过多说明了

代码语言:javascript
复制
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;

public class LikeView extends View {

    private static final String DEFAULT_TEXT_COLOR = "#cccccc";
    private static final int ANIM_TIME = 300;
    private int mCurrValue;
    // true 字符相同,false 不同
    private boolean[] mArrayStatus;
    private Paint mTextPaint;
    private int mTextSize;
    private int mTextOffY;
    private boolean mIsLike;
    private float mCurrOffsetY;
    private int mSingleTextWidth;

    public LikeView(Context context) {
        super(context);
        init(context);
    }

    public LikeView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

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

    private void init(Context context) {
        mTextSize = sp2px(context, 16f);
        mTextOffY = mTextSize / 2;
        mTextPaint = new Paint();
        mTextPaint.setAntiAlias(true);
        mTextPaint.setTextSize(mTextSize);
        mTextPaint.setColor(Color.parseColor(DEFAULT_TEXT_COLOR));
        mSingleTextWidth = measureWidth("9");
    }

    private int sp2px(Context context, float spValue) {
        final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
        return (int) (spValue * fontScale + 0.5f);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int width = measureWidth(String.valueOf(mCurrValue)) + getPaddingLeft() + getPaddingRight();
        int height = mTextSize + getPaddingTop() + getPaddingBottom();
        if (View.MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.EXACTLY) {
            width = Math.max(width, MeasureSpec.getSize(widthMeasureSpec));
        }
        if (View.MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.EXACTLY) {
            height = Math.max(width, MeasureSpec.getSize(heightMeasureSpec));
        }
        setMeasuredDimension(width, height);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        String content = String.valueOf(mCurrValue);
        int offX = getPaddingLeft();
        int offY = getPaddingTop() + mTextSize;
        if (null == mArrayStatus || mArrayStatus.length != content.length()) {
            canvas.drawText(content, offX, offY, mTextPaint);
        } else {
            int currLeft = offX;
            int strLength = content.length() - 1;
            for (int i = 0, y = content.length(); i < y; i++) {
                if (mArrayStatus[strLength]) {
                    canvas.drawText(String.valueOf(content.charAt(i)), currLeft, offY, mTextPaint);
                } else {
                    canvas.drawText(String.valueOf(content.charAt(i)), currLeft, offY + mCurrOffsetY, mTextPaint);
                }
                currLeft += mSingleTextWidth;
                strLength--;
            }
        }
    }

    private int measureWidth(String content) {
        return (int) Math.ceil(mTextPaint.measureText(content));
    }

    public void setCurrValue(int currValue) {
        this.mCurrValue = currValue;
        requestLayout();
    }

    public void setLike() {
        setLike(!mIsLike);
    }

    public void setLike(boolean isLike) {
        setLike(isLike, 1);
    }

    public void setLike(boolean isLike, int value) {
        this.mIsLike = isLike;
        int lastValue = mCurrValue;
        if (isLike) {
            lastValue += value;
        } else {
            lastValue -= value;
        }
        findDiff(String.valueOf(mCurrValue), String.valueOf(lastValue));
        mCurrValue = lastValue;
        startAnim();
    }

    private void findDiff(String currStr, String lastStr) {
        if (null == currStr || null == lastStr || currStr.equals(lastStr)) {
            return;
        }
        int currStrLength = currStr.length() - 1;
        int lastStrLength = lastStr.length() - 1;
        int maxLength = Math.max(currStr.length(), lastStr.length());
        mArrayStatus = new boolean[maxLength];
        for (int i = 0; i < maxLength; i++) {
            if (currStrLength >= 0 && lastStrLength >= 0) {
                char c1 = currStr.charAt(currStrLength);
                char c2 = lastStr.charAt(lastStrLength);
                mArrayStatus[i] = c1 == c2;
                currStrLength--;
                lastStrLength--;
            } else {
                mArrayStatus[i] = false;
            }
        }
    }

    public void setTextOffY(float offsetY) {
        float value = mTextOffY * offsetY;
        this.mCurrOffsetY = mIsLike ? value : -value;
        invalidate();
    }

    private void startAnim() {
        @SuppressLint("ObjectAnimatorBinding") ObjectAnimator anim = ObjectAnimator.ofFloat(this, "textOffY"
                , 1, 0);
        anim.setDuration(ANIM_TIME);
        anim.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
                mArrayStatus = null;
                mCurrOffsetY = 0;
            }
        });
        anim.start();
    }

}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2021/11/16 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档