自定义控件--数字的滚轮式增加

作为一个出水不忘挖井人的小码仔,今天算是第一次正式发表博客,不求文章质量怎么样,但求能帮到有需要的人。
目前许多游戏中的一些参数,如分数、金币数在变化的时候都是数字蹭蹭蹭的往上涨,不断变化。今天我就分享一下我通过参考别人再自己做过改良的自定义控件。
废话不说,先上代码:

控件:

public class NumberTextView extends TextView implements IRiseNumber{
    private static final int STOPPED = 0;

    private static final int RUNNING = 1;

    private int mPlayingState = STOPPED;

    private float number;

    private float fromNumber;

    private int textColor;           // 数字的颜色
    private int textSize;            // 数字的字号

    /**
     * 默认时长
     */
    private long duration = 1000;
    /**
     * 1.int 2.float
     */
    private int numberType = 2;

    private DecimalFormat fnum;

    private EndListener mEndListener = null;

    final static int[] sizeTable = {9, 99, 999, 9999, 99999, 999999, 9999999,
            99999999, 999999999, Integer.MAX_VALUE};

    /**
     * 构造方法
     *
     * @param context
     */
    public NumberTextView(Context context) {
        super(context);
    }

    /**
     * 构造方法
     *
     * @param context
     * @param attr
     */
    public NumberTextView(Context context, AttributeSet attr) {
        super(context, attr);
        TypedArray array = context.obtainStyledAttributes(attr, R.styleable.NumberTextView);
        if(array != null){
            textColor = array.getColor(R.styleable.NumberTextView_numberColor, Color.BLACK);
            textSize = array.getInt(R.styleable.NumberTextView_numberSize, 20);
        }
        setTextColor(textColor);
        setTextSize(textSize);
    }

    public NumberTextView(Context context, AttributeSet attr, int defStyle) {
        super(context, attr, defStyle);
        TypedArray array = context.obtainStyledAttributes(attr, R.styleable.NumberTextView);
        if(array != null){
            textColor = array.getColor(R.styleable.NumberTextView_numberColor, Color.BLACK);
            textSize = array.getInt(R.styleable.NumberTextView_numberSize, 20);
        }
        setTextColor(textColor);
        setTextSize(textSize);
    }

    /**
     * 动画是否正在执行
     *
     * @return
     */
    public boolean isRunning() {
        return (mPlayingState == RUNNING);
    }

    /**
     * 浮点型数字变动
     */
    private void runFloat() {
        ValueAnimator valueAnimator = ValueAnimator.ofFloat(fromNumber, number);
        valueAnimator.setDuration(duration);

        valueAnimator
                .addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                    @Override
                    public void onAnimationUpdate(ValueAnimator valueAnimator) {

                        setText(fnum.format(Float.parseFloat(valueAnimator
                                .getAnimatedValue().toString())));
                        if (valueAnimator.getAnimatedFraction() >= 1) {
                            mPlayingState = STOPPED;
                            if (mEndListener != null)
                                mEndListener.onEndFinish();
                        }
                    }

                });

        valueAnimator.start();
    }

    /**
     * 整型数字变动
     */
    private void runInt() {

        ValueAnimator valueAnimator = ValueAnimator.ofInt((int) fromNumber,
                (int) number);
        valueAnimator.setDuration(duration);

        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                    @Override
                    public void onAnimationUpdate(ValueAnimator valueAnimator) {
                        setText(valueAnimator.getAnimatedValue().toString());
                        if (valueAnimator.getAnimatedFraction() >= 1) {
                            mPlayingState = STOPPED;
                            if (mEndListener != null)
                                mEndListener.onEndFinish();
                        }
                    }
                });
        valueAnimator.start();
    }

    static int sizeOfInt(int x) {
        for (int i = 0; ; i=i+10) {
            if (x <= sizeTable[i])
                return i + 10;
        }
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        fnum = new DecimalFormat("##0");
    }

    /**
     * 开始动画
     */
    @Override
    public void start() {

        if (!isRunning()) {
            mPlayingState = RUNNING;
            if (numberType == 1)
                runInt();
            else
                runFloat();
        }
    }


    /**
     * 设置数字(整数型)
     * @param number
     */
    @Override
    public void withNumber(int number) {
        this.number = number;
        numberType = 1;
        if (number > 1000) {
            fromNumber = number
                    - (float) Math.pow(10, sizeOfInt((int) number) - 2);
        } else {
            fromNumber = number / 2;
        }
    }

    /**
     * 设置数字(浮点型)
     * @param number
     */
    @Override
    public void withNumber(float number) {

        this.number = number;
        numberType = 2;
        if (number > 1000) {
            fromNumber = number
                    - (float) Math.pow(10, sizeOfInt((int) number) - 1);
        } else {
            fromNumber = number / 2;
        }

    }

    /**
     * 设置 开始 和 结束 数字(整数型)
     * @param fromNumber
     * @param endNumber
     */
    @Override
    public void setFromAndEndNumber(int fromNumber, int endNumber) {
        this.fromNumber = fromNumber;
        this.number = endNumber;
        numberType = 1;
    }

    /**
     * 设置 开始 和 结束 数字(浮点型)
     * @param fromNumber
     * @param endNumber
     */
    @Override
    public void setFromAndEndNumber(float fromNumber, float endNumber) {
        this.fromNumber = fromNumber;
        this.number = endNumber;
        numberType = 2;
    }

    /**
     * 设置动画时长
     */
    @Override
    public void setDuration(long duration) {
        this.duration = duration;
    }

    /**
     * 设置动画结束监听
     */
    @Override
    public void setOnEndListener(EndListener callback) {
        mEndListener = callback;
    }

    /**
     * 动画结束接口
     */
    public interface EndListener {
        /**
         * 动画结束
         */
        public void onEndFinish();
    }
}

看起来不少,其实方法就那几个。
至于用到的接口就在这里

接口类:

public interface IRiseNumber {
        public void start();

        public void withNumber(int number);

        public void withNumber(float number);

        public void setFromAndEndNumber(int startNum, int EndNum);

        public void setFromAndEndNumber(float startNum, float EndNum);

        public void setDuration(long time);

        public void setOnEndListener(NumberTextView.EndListener listener);
    }

控件中有两个自定义属性,这个需要你在res/values/attrs中添加

attrs.xml

<declare-styleable name="NumberTextView">
        <attr name="numberColor" format="color|reference"/>
        <attr name="numberSize" format="integer|reference"/>
    </declare-styleable>

于是在布局中

xml布局:

<com.test.myView.NumberTextView
        android:id="@+id/tv_numberToAdd"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="0"
        app:numberColor="@color/colorBlue"
        app:numberSize="30" />

最后就是在代码中调用了

private NumberTextView tv_addNumber;
public void addNumberClick(View view) {

        tv_addNumber.setFromAndEndNumber(0, 100);  //设置开始和结束的数字,支持整数型和浮点型
        //
        tv_addNumber.setDuration(1500);  //设置动画时间
        tv_addNumber.start();            //开始动画
    }

调用start()方法,就可以看到数字蹭蹭蹭的涨了。
就到这里吧,希望对大家有哪怕一丢丢帮助。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值