Skip to content

Commit

Permalink
改良NumRunningTextView
Browse files Browse the repository at this point in the history
  • Loading branch information
chaychan committed Jun 17, 2017
1 parent 4458416 commit b0db7c1
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 97 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ protected void onCreate(Bundle savedInstanceState) {
initView();
initListener();

tvMoney.setContent("1354.00");
tvNum.setContent("200");
tvMoney.setContent("1454.00");
tvNum.setContent("300");
}

private void initView(){
Expand Down
132 changes: 39 additions & 93 deletions viewlib/src/main/java/com/chaychan/viewlib/NumberRunningTextView.java
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
package com.chaychan.viewlib;

import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.TypedArray;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.widget.TextView;

import com.chaychan.viewlib.utils.StringUtils;

import java.text.DecimalFormat;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
* 数字滚动的textView
Expand All @@ -22,21 +19,17 @@ public class NumberRunningTextView extends TextView {
private static final int MONEY_TYPE = 0;
private static final int NUM_TYPE = 1;

private int frameNum;// 总共跳跃的帧数,默认30跳
private int textType;//内容的类型,默认是金钱类型
private boolean useCommaFormat;//是否使用每三位数字一个逗号的格式,让数字显得比较好看,默认使用
private boolean runWhenChange;//是否当内容有改变才使用动画,默认是
private int duration;//动画的周期,默认为800ms
private int minNum;//显示数字最少要达到这个数字才滚动 默认为1
private float minMoney;//显示金额最少要达到这个数字才滚动 默认为0.3

private ExecutorService threadPool = Executors.newFixedThreadPool(1);// 1个线程的线程池;
private DecimalFormat formatter = new DecimalFormat("0.00");// 格式化金额,保留两位小数

private double nowMoneyNum = 0.00;// 记录每帧增加后的金额数字
private double finalMoneyNum;// 目标金额数字(最终的金额数字)

private int nowNum;//记录每帧增加后的数字
private int finalNum;//目标数字(最终的数字)
private String preStr;


public NumberRunningTextView(Context context) {
this(context, null);
}
Expand All @@ -49,10 +42,12 @@ public NumberRunningTextView(Context context, AttributeSet attrs, int defStyleAt
super(context, attrs, defStyleAttr);

TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.NumberRunningTextView);
frameNum = ta.getInt(R.styleable.NumberRunningTextView_frameNum, 30);
duration = ta.getInt(R.styleable.NumberRunningTextView_duration, 1000);
textType = ta.getInt(R.styleable.NumberRunningTextView_textType, MONEY_TYPE);
useCommaFormat = ta.getBoolean(R.styleable.NumberRunningTextView_useCommaFormat, true);
runWhenChange = ta.getBoolean(R.styleable.NumberRunningTextView_runWhenChange,true);
minNum = ta.getInt(R.styleable.NumberRunningTextView_minNum, 3);
minMoney = ta.getFloat(R.styleable.NumberRunningTextView_minMoney,0.1f);

ta.recycle();
}
Expand Down Expand Up @@ -88,7 +83,7 @@ public void setContent(String str) {
private void useAnimByType(String str) {
if (textType == MONEY_TYPE) {
playMoneyAnim(str);
} else {
} else if (textType == NUM_TYPE){
playNumAnim(str);
}
}
Expand All @@ -102,27 +97,33 @@ private void useAnimByType(String str) {
public void playMoneyAnim(String moneyStr) {
String money = moneyStr.replace(",", "").replace("-", "");//如果传入的数字已经是使用逗号格式化过的,或者含有符号,去除逗号和负号
try {
finalMoneyNum = Double.parseDouble(money);
if (finalMoneyNum == 0) {
float finalFloat = Float.parseFloat(money);
if (finalFloat < minMoney) {
//如果传入的为0,则直接使用setText()
NumberRunningTextView.this.setText(moneyStr);
setText(moneyStr);
return;
}
nowMoneyNum = 0;
threadPool.execute(new Runnable() {
ValueAnimator floatAnimator = ValueAnimator.ofFloat(0, finalFloat);
floatAnimator.setDuration(duration);
floatAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void run() {
Message msg = handler.obtainMessage();
double size = finalMoneyNum / frameNum;//数字除以帧数,得到每帧跳跃的大小
msg.what = MONEY_TYPE;
msg.obj = size < 0.01 ? 0.01 : size;// 如果每帧的间隔比0.01小,就设置为0.01
handler.sendMessage(msg);// 发送通知改变UI
public void onAnimationUpdate(ValueAnimator animation) {
float currentNum = (float) animation.getAnimatedValue();
String str = formatter.format(Double.parseDouble(String.valueOf(currentNum)));//格式化成两位小数
// 更新显示的内容
if (useCommaFormat) {
//使用每三位数字一个逗号的格式
String formatStr = StringUtils.addComma(str);//三位一个逗号格式的字符串
setText(formatStr);
} else {
setText(str);
}
}
});

floatAnimator.start();
} catch (NumberFormatException e) {
e.printStackTrace();
NumberRunningTextView.this.setText(moneyStr);//如果转换Double失败则直接用setText
this.setText(moneyStr);//如果转换Double失败则直接用setText
}
}

Expand All @@ -134,80 +135,25 @@ public void run() {
public void playNumAnim(String numStr) {
String num = numStr.replace(",", "").replace("-", "");//如果传入的数字已经是使用逗号格式化过的,或者含有符号,去除逗号和负号
try {
finalNum = Integer.parseInt(num);
if (finalNum < frameNum) {
int finalNum = Integer.parseInt(num);
if (finalNum < minNum) {
//由于是整数,每次是递增1,所以如果传入的数字比帧数小,则直接使用setText()
NumberRunningTextView.this.setText(numStr);
this.setText(numStr);
return;
}
nowNum = 0;// 默认都是从0开始动画
threadPool.execute(new Runnable() {
ValueAnimator intAnimator = new ValueAnimator().ofInt(0, finalNum);
intAnimator.setDuration(duration);
intAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void run() {
Message msg = handler.obtainMessage();
int temp = finalNum / frameNum;//数字除以帧数,得到每帧跳跃的大小
msg.what = NUM_TYPE;
msg.obj = temp;
handler.sendMessage(msg);// 发送通知改变UI
public void onAnimationUpdate(ValueAnimator animation) {
int currentNum = (int) animation.getAnimatedValue();
setText(String.valueOf(currentNum));
}
});

intAnimator.start();
} catch (NumberFormatException e) {
e.printStackTrace();
NumberRunningTextView.this.setText(numStr);//如果转换Double失败则直接用setText
setText(numStr);//如果转换Double失败则直接用setText
}
}

private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case MONEY_TYPE://金钱数字的滚动
String str = formatter.format(nowMoneyNum).toString();//保留两位小数的字符串

// 更新显示的内容
if (useCommaFormat) {
//使用每三位数字一个逗号的格式
String formatStr = StringUtils.addComma(str);//三位一个逗号格式的字符串
NumberRunningTextView.this.setText(formatStr);
} else {
NumberRunningTextView.this.setText(str);
}

nowMoneyNum += (double) msg.obj;//记录当前每帧递增后的数字

if (nowMoneyNum < finalMoneyNum) {
//如果当前记录的金额数字小于目标金额数字,即还没达到目标金额数字,继续递增
Message msg2 = handler.obtainMessage();
msg2.what = MONEY_TYPE;
msg2.obj = msg.obj;
handler.sendMessage(msg2);// 继续发送通知改变UI
} else {
//已经达到目标的金额数字,显示最终的数字
if (useCommaFormat) {
NumberRunningTextView.this.setText(StringUtils.addComma(formatter.format(finalMoneyNum)));
} else {
NumberRunningTextView.this.setText(formatter.format(finalMoneyNum));
}
}
break;

case NUM_TYPE://普通数字滚动
NumberRunningTextView.this.setText(String.valueOf(nowNum));
nowNum += (Integer) msg.obj;//记录当前每帧递增后的数字
if (nowNum < finalNum) {
//如果当前记录的数字小于目标数字,即还没达到目标数字,继续递增
Message msg2 = handler.obtainMessage();
msg2.what = NUM_TYPE;
msg2.obj = msg.obj;
handler.sendMessage(msg2);// 继续发送通知改变UI
} else {
//已经达到目标的数字,显示最终的内容
NumberRunningTextView.this.setText(String.valueOf(finalNum));
}
break;
}
}
};
}
5 changes: 3 additions & 2 deletions viewlib/src/main/res/values/attr.xml
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,9 @@
</declare-styleable>

<declare-styleable name="NumberRunningTextView">
<!--帧数-->
<attr name="frameNum" format="integer"></attr>
<attr name="duration" format="integer"></attr>
<attr name="minNum" format="integer"></attr>
<attr name="minMoney" format="float"></attr>
<!--内容的格式-->
<attr name="textType">
<enum name="money" value="0"></enum>
Expand Down

0 comments on commit b0db7c1

Please sign in to comment.