IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Android TextView 仿动控件 -> 正文阅读

[移动开发]Android TextView 仿动控件

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

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

}
  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-11-18 11:17:50  更:2021-11-18 11:17:54 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 3:34:41-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码