利用RiseNumberTextView组件简单实现数字滚动效果

利用RiseNumberTextView组件简单实现数字滚动效果

一、简介

在日常开发需求中,很多时候需要向用户展现数字变化的动态效果,比如余额,正确率之类的变化,使得用户更直观地感受数字的变动,因此本文主要介绍如何使用开源组件RiseNumberTextView来实现类似支付宝界面余额变动的效果。

效果:
在这里插入图片描述

二、前期准备

  1. 下载jar包: https://github.com/downloads/JakeWharton/NineOldAndroids/nineoldandroids-2.4.0.jar
  2. 将下载好的jar包复制到app/libs目录下
    下载jar包
  3. 右键点击jar包,选择Add As Library,将该jar包导入库中
    导入库

三、编写组件

  1. 创建一个包存放组件的接口与类文件
    创建包
  2. RiseNumberBase 接口声明
    接口说明:
接口说明
start()开始滚动效果
withNumber(float number)显示浮点型数字
withNumber(int number)显示整型数字
setDuration(long duration)持续时间
package lib;

public interface RiseNumberBase {
    public void start();
    public RiseNumberTextView withNumber(float number);
    public RiseNumberTextView withNumber(int number);
    public RiseNumberTextView setDuration(long duration);
    public void setOnEnd(RiseNumberTextView.EndListener callback);
}

  1. RiseNumberTextView 接口实现,如果想修改数字滚动功能,可在下面的代码中修改
package lib;

import android.content.Context;
import android.util.AttributeSet;
import android.widget.TextView;

import com.nineoldandroids.animation.ValueAnimator;  //使用到刚才导入的jar包

import java.text.DecimalFormat;

/*RiseNumberTextView继承了TextView来实现接口RiseNumberBase*/
public class RiseNumberTextView extends TextView implements RiseNumberBase{

    private static final int STOPPED = 0;

    private static final int RUNNING = 1;

    private int mPlayingState = STOPPED;

    private float number;

    private float fromNumber;

    private long duration=1500;

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

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

    public RiseNumberTextView(Context context,AttributeSet attr){
        super(context,attr);
    }

    public RiseNumberTextView(Context context,AttributeSet attr,int defStyle)
    {
        super(context,attr,defStyle);
    }

    public interface EndListener {
        public void onEndFinish();
    }

	/*判断滚动状态*/
    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++)
            if (x <= sizeTable[i])
                return i + 1;
    }

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

	/*定义开始滚动*/
    @Override
    public void start() {

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

	/*
		**
	这边定义了如何选择滚动效果的初始数字
	如果数字小于100,则初始数字为500
	如果数字大于1000,则初始数字为:显示数字-10^(显示数字的位数-2)
	*/
    @Override
    public RiseNumberTextView withNumber(float number) {

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

        return this;
    }

    @Override
    public RiseNumberTextView 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;
        }

        return this;

    }

    @Override
    public RiseNumberTextView setDuration(long duration) {
        this.duration=duration;
        return this;
    }

    @Override
    public void setOnEnd(EndListener callback) {
        mEndListener=callback;
    }


}

四、组件编写完毕,开始使用

本示例模仿支付宝余额界面,通过点击充值与提现按钮使余额数字产生滚动效果。

  1. 在MainActivity中声明一个RiseNumberTextView组件,并设置两个按钮点击事件,使得点击按钮触发数字滚动
package com.hymn.rise;

import androidx.appcompat.app.AppCompatActivity;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;

import lib.RiseNumberTextView;  //记得导入组件类

public class MainActivity extends AppCompatActivity {

    private RiseNumberTextView RNTextView;  //声明一个数字滚动组件

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        RNTextView=(RiseNumberTextView)findViewById(R.id.text);//给组件套上样式
		
		/* 设置按钮点击事件 */
        findViewById(R.id.chongzhi).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                init();
            }
        });


    	findViewById(R.id.tixian).setOnClickListener(new View.OnClickListener() {

        public void onClick(View w ) {
            init();
        }
    });

    init();
}

    private void init(){
        RNTextView.withNumber(99999).start();
    }
}

  1. 编写activity_main.xml,使用线性布局放置一个数字滚动组件与两个按钮
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="300dp"
    android:orientation="vertical"
    tools:context=".MainActivity">


    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="70dp"
        android:layout_weight="2"
        android:background="#03A9F4"
        android:orientation="vertical"
        android:padding="15dp">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="余额(元)"
            android:textColor="#CFCFCF"
            android:textSize="22sp" />

        <lib.RiseNumberTextView
            android:id="@+id/text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="20dp"
            android:textColor="#FFFFFF"
            android:textSize="48sp" />
    </LinearLayout>


    <TextView
        android:id="@+id/chongzhi"
        android:layout_width="match_parent"
        android:layout_height="30dp"
        android:layout_weight="0.5"
        android:background="#59AAAD"
        android:drawableLeft="@drawable/chong"
        android:gravity="center"
        android:text="充值"
        android:textColor="#ffffff"
        android:textSize="18sp" />

    <TextView
        android:id="@+id/tixian"
        android:layout_width="match_parent"
        android:layout_height="30dp"
        android:layout_weight="0.5"
        android:gravity="center"
        android:drawableLeft="@drawable/chong"
        android:textColor="#ffffff"
        android:textSize="18sp"
        android:text="提现"
        android:background="#7EA0AF"/>

</LinearLayout>

参考

https://github.com/sd6352051/RiseNumber

作者:陈良俊
原文链接:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值