NumberAnimTextView

本文介绍了一个自定义的数字动画TextView组件,该组件可在Android应用中实现数字动态增长效果,并支持设置前后缀文字、动画时长等功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

开始的数字是0,然后,使用动画是数字滚动起来。监听动画的变化,然后不断刷新页面。

自定义的数字动画 TextView

package me.bakumon.numberanimtextview;

import android.animation.TypeEvaluator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.util.AttributeSet;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.widget.TextView;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.text.DecimalFormat;

/**
 * 数字增加动画的 TextView
 * Created by bakumon on 16-11-26.
 */
public class NumberAnimTextView extends TextView {

    private String mNumStart = "0";  //
    private String mNumEnd; //

    private long mDuration = 2000; //

    private String mPrefixString = ""; // 前缀
    private String mPostfixString = ""; //后缀

    public NumberAnimTextView(Context context) {
        super(context);
    }

    public NumberAnimTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public NumberAnimTextView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public void setNumberString(String number) {
        setNumberString("0", number);
    }

    public void setNumberString(String numberStart, String numberEnd) {
        mNumStart = numberStart;
        mNumEnd = numberEnd;
        if (checkNumString(numberStart, numberEnd)) {
            // 数字合法 开始数字动画
            start();
        } else {
            // 数字不合法 直接调用 setText 设置最终值
            setText(mPrefixString + numberEnd + mPostfixString);
        }
    }

    public void setDuration(long mDuration) {
        this.mDuration = mDuration;
    }

    public void setPrefixString(String mPrefixString) {
        this.mPrefixString = mPrefixString;
    }

    public void setPostfixString(String mPostfixString) {
        this.mPostfixString = mPostfixString;
    }

    private boolean isInt; // 是否是整数

    /**
     * 校验数字的合法性
     *
     * @param numberStart  开始的数字
     * @param numberEnd    结束的数字
     * @return 合法性
     */
    private boolean checkNumString(String numberStart, String numberEnd) {
        try {
            new BigInteger(numberStart);
            new BigInteger(numberEnd);
            isInt = true;
        } catch (Exception e) {
            isInt = false;
            e.printStackTrace();
        }
        try {
            BigDecimal start = new BigDecimal(numberStart);
            BigDecimal end = new BigDecimal(numberEnd);
            return end.compareTo(start) >= 0;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    private void start() {
        ValueAnimator animator = ValueAnimator.ofObject(new BigDecimalEvaluator(), new BigDecimal(mNumStart), new BigDecimal(mNumEnd));
        animator.setDuration(mDuration);
        animator.setInterpolator(new AccelerateDecelerateInterpolator());
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                BigDecimal value = (BigDecimal) valueAnimator.getAnimatedValue();
                setText(mPrefixString + format(value) + mPostfixString);
            }
        });
        animator.start();
    }

    /**
     * 格式化 BigDecimal ,小数部分时保留两位小数并四舍五入
     *
     * @param bd  BigDecimal
     * @return 格式化后的 String
     */
    private String format(BigDecimal bd) {
        String pattern;
        if (isInt) {
            pattern = "#,###";
        } else {
            pattern = "#,##0.00";
        }
        DecimalFormat df = new DecimalFormat(pattern);
        return df.format(bd);
    }

    class BigDecimalEvaluator implements TypeEvaluator {
        @Override
        public Object evaluate(float fraction, Object startValue, Object endValue) {
            BigDecimal start = (BigDecimal) startValue;
            BigDecimal end = (BigDecimal) endValue;
            BigDecimal result = end.subtract(start);
            return result.multiply(new BigDecimal("" + fraction)).add(start);
        }
    }
}
Activity中使用:

package io.github.bakumon.numberanimtextview;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;

import me.bakumon.numberanimtextview.NumberAnimTextView;


public class MainActivity extends AppCompatActivity {

    private NumberAnimTextView mNumberAnimTextView;
    private NumberAnimTextView mNumberAnimTextView1;
    private NumberAnimTextView mNumberAnimTextView2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mNumberAnimTextView = (NumberAnimTextView) findViewById(R.id.text);
        mNumberAnimTextView1 = (NumberAnimTextView) findViewById(R.id.text1);
        mNumberAnimTextView2 = (NumberAnimTextView) findViewById(R.id.text2);
    }

    public void start(View view) {
        mNumberAnimTextView.setPrefixString("¥");
        mNumberAnimTextView.setNumberString("1111.75", "98765432.75");

        mNumberAnimTextView1.setNumberString("1234567");

        mNumberAnimTextView2.setPostfixString("%");
        mNumberAnimTextView2.setNumberString("19.75", "99.75");

    }
}
转载来源于:https://github.com/Bakumon/NumberAnimTextView


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值