In a previous project, there is a gold coin attribute. When you want to add gold coins, you need to scroll like a slot machine, find the information on the Internet, summarize it, and share it with you.
Let's start with the picture (git doesn't work, let's imagine)
Usage method
1. Create attrs.xml file under res/values to change font size and color
<declare-styleable name="NumberTextView">
<attr name="numberColor" format="color|reference"/>
<attr name="numberSize" format="integer|reference"/>
</declare-styleable>
2. Using in xml file
<com.interjoy.networkdemo.myView.NumberTextView
android:id="@+id/tv_numberToAdd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="0"
app:numberColor="@color/colorAccent" //Font color
app:numberSize="30" /> //font size
3. Call in activity or Fragment
tv_addNumber.setFromAndEndNumber(currentNum, num); //Set start and end numbers, integer and floating point supported
tv_addNumber.setDuration(1500); //Set scroll time
tv_addNumber.start(); //Start scrolling```
Next, we serve the hard dishes and scroll the font entity class
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; // Color of numbers
private int textSize; // Number font size
/**
* Default duration
*/
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};
/**
* Construction method
*
* @param context
*/
public NumberTextView(Context context) {
super(context);
}
/**
* Construction method
*
* @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);
}
/**
* Is the animation executing
*
* @return
*/
public boolean isRunning() {
return (mPlayingState == RUNNING);
}
/**
* Floating point number change
*/
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();
}
/**
* Integer number change
*/
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");
}
/**
* Start animation
*/
@Override
public void start() {
if (!isRunning()) {
mPlayingState = RUNNING;
if (numberType == 1)
runInt();
else
runFloat();
}
}
/**
* Set number (integer)
* @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;
}
}
/**
* Set number (floating point)
* @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;
}
}
/**
* Set start and end numbers (integer)
* @param fromNumber
* @param endNumber
*/
@Override
public void setFromAndEndNumber(int fromNumber, int endNumber) {
this.fromNumber = fromNumber;
this.number = endNumber;
numberType = 1;
}
/**
* Set start and end numbers (floating point)
* @param fromNumber
* @param endNumber
*/
@Override
public void setFromAndEndNumber(float fromNumber, float endNumber) {
this.fromNumber = fromNumber;
this.number = endNumber;
numberType = 2;
}
/**
* Animation duration
*/
@Override
public void setDuration(long duration) {
this.duration = duration;
}
/**
* Set animation end listening
*/
@Override
public void setOnEndListener(EndListener callback) {
mEndListener = callback;
}
/**
* Animation end interface
*/
public interface EndListener {
/**
* End of animation
*/
public void onEndFinish();
}
}
An interface is also required
"`
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); }```