美文网首页我要实现
Android TextView 仿动控件

Android TextView 仿动控件

作者: markRao | 来源:发表于2021-11-16 11:49 被阅读0次

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


    50buq-l34h1.gif

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

    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();
        }
    
    }
    
    

    相关文章

      网友评论

        本文标题:Android TextView 仿动控件

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