Number Running TextView

For reprinting, please indicate the source: http://blog.csdn.net/chay_chan/article/details/70196478

Introduction to NumberRunning TextView

Number Running TextView is a TextView with its own digital scrolling animation. By using setContent(String str) method, the corresponding amount of digital string (such as "1354.00") or digital string (such as 200) is passed in. When the page is initialized, the effect of digital scrolling and payment can be seen. When Baozhong enters the interface of Baozhong, the effect of rolling the balance is similar. The specific effect is as follows:

Use

In the layout file, use NumberRunning TextView, code as follows:

Number Running TextView demonstrating scrolling amounts

 <com.chaychan.viewlib.NumberRunningTextView
            android:id="@+id/tv_money"
            android:layout_width="wrap_content"
            android:layout_height="wrap_cointent"
            android:layout_centerInParent="true"
            android:text="0.00"
            android:textColor="#fff"
            android:textSize="30sp"
            android:textStyle="bold"
            />

Number Running TextView Demonstrating Integer Digital Scrolling

 <com.chaychan.viewlib.NumberRunningTextView
            android:id="@+id/tv_num"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:text="200"
            android:textColor="#fff"
            android:textSize="30sp"
            app:textType="num"
            />

The difference between them is the setting of textType. TextType is a format used to specify content. There are money (money format, decimal format) and num (integer format). The default is money format. If textType is not configured, the default is money format.

After the corresponding view is found in the java file according to id, the setContent() method is called.

 tvMoney.setContent("1354.00");
 tvNum.setContent("200");

Turn off automatic formatting of amounts (add a comma for every three digits)

_As shown in the figure above, the final amount figure is processed and a comma is added to each three, which makes the figure look good. The default amount is in this format. If you don't want the number in this format, you can set useComma Format to NumberRunning TextView in the layout file. false, so that the final number is not comma, the effect is as follows:

Close the time to execute animation

_When the initialization data is finished and the NumberRunning TextView setting data is finished, the animation of digital scrolling is automatically executed. If refresh operation is carried out, new data is obtained from the server and data is reset, NumberRunning TextView will automatically judge whether the incoming content has changed. If there is no change, it will not roll again, which is similar to the amount in Alipay's balance treasure interface. When the balance interface is pulled down, the amount will not change, the number will not roll again, and when it is returned to the interface after the presentation, the amount will change once it changes, and it will roll again. The effect is as follows:

In SwipeRefreshLayout's refresh callback, only this is done, and the content set by NumberRunning TextView is the original data.

 srlRoot.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
        @Override
        public void onRefresh() {
            tvMoney.setContent("1354.00");
            tvNum.setContent("200");
            srlRoot.setRefreshing(false);
        }
    });

When you do drop-down refresh, if the content does not change, the number will not scroll. If the content changes, the number will scroll again. Here, modify the drop-down refresh code to simulate the data changes. Demonstrate:

 srlRoot.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
        @Override
        public void onRefresh() {
            tvMoney.setContent("1454.00");
            tvNum.setContent("300");
            srlRoot.setRefreshing(false);
        }
    });

The results are as follows:

If you want to perform scrolling animation when refreshing, no matter whether the content changes or not, you can set runWhenChange to false in the configuration of NumberRunning TextView in the layout file. At this time, whether the content changes or not, you will perform scrolling animation. The effect is as follows:

Modify the number of frames

Number Running TextView defaults to 30 frames. If you need to change the number of frames, you can set the frame Num as the number of frames you want in the layout file, Number Running TextView configuration.

NumberRunning TextView Source Parsing

The principle of NumberRunning TextView is very simple. It divides a number by the number of frames (default is 30 frames) and increments each segment by a fixed size.

Firstly, the properties of NumberRunning TextView customization are introduced.

<declare-styleable name="NumberRunningTextView">
    <! - Number of frames - >
    <attr name="frameNum" format="integer"></attr>
    <! - The format of the content - >
    <attr name="textType">
        <enum name="money" value="0"></enum>
        <enum name="num" value="1"></enum>
    </attr>
    <! - Whether to use a comma for every three digits
    <attr name="useCommaFormat" format="boolean"></attr>
    <! - Whether to use animation when content changes, and not animation if it does not change - >
    <attr name="runWhenChange" format="boolean"></attr>

</declare-styleable>

NumberRunning TextView inherits from TextView

public class NumberRunningTextView extends TextView {

    public NumberRunningTextView(Context context) {
        this(context, null);
    }

    public NumberRunningTextView(Context context, AttributeSet attrs) {
        this(context, attrs, android.R.attr.textViewStyle);
    }

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

        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.NumberRunningTextView);
        frameNum = ta.getInt(R.styleable.NumberRunningTextView_frameNum, 30);
        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);
    }

    ...

}

When the setContent() method is called, the corresponding judgment is made.

  /**
 * Set a string of money (must be positive) or integer (must be positive) that needs to be scrolled
 *
 * @param str
 */
public void setContent(String str) {
    //If the scroll animation is performed only when the content changes, determine whether the content has changed.
    if (runWhenChange){
        if (TextUtils.isEmpty(preStr)){
            //If the last str is empty
            preStr = str;
            useAnimByType(str);
            return;
        }

        //If the last str is not empty, determine whether the two contents are consistent
        if (preStr.equals(str)){
            //If the two contents are identical, they are not processed.
            return;
        }

        preStr = str;//If the two contents are inconsistent, record the latest str
    }

    useAnimByType(str);
}

If runWhenChange is true, that is, when the content changes, it will scroll. If the last content is empty (that is, the first setup), it will scroll. Otherwise, it will judge whether the content is consistent with the last one. If the content is consistent, it will not be processed. If the content is inconsistent, that is, the content. Changes have taken place, recording the current content and performing the corresponding scrolling operation.

The useAnimByType() method is only used to determine the type of content and execute the corresponding animation. The core of NumRunning TextView is playMoneyAnim() and playNumAnim().

  private void useAnimByType(String str) {
    if (textType == MONEY_TYPE) {
        playMoneyAnim(str);
    } else {
        playNumAnim(str);
    }
}

The following two methods are analyzed:

/**
 * Method of Playing Money Digital Animation
 *
 * @param moneyStr
 */
public void playMoneyAnim(String moneyStr) {
    String money = moneyStr.replace(",", "").replace("-", "");//If the incoming number has been formatted using commas or contains symbols, remove commas and minus signs
    try {
        finalMoneyNum = Double.parseDouble(money);
        if (finalMoneyNum == 0) {
            //If 0 is passed in, use setText()
            NumberRunningTextView.this.setText(moneyStr);
            return;
        }
        nowMoneyNum = 0;//Record the number of increments per frame, starting at 0
        threadPool.execute(new Runnable() {
            @Override
            public void run() {
                Message msg = handler.obtainMessage();
                double size = finalMoneyNum / frameNum;//Divide the number of frames to get the hop size of each frame
                msg.what = MONEY_TYPE;
                msg.obj = size < 0.01 ? 0.01 : size;// If the interval per frame is smaller than 0.01, set it to 0.01.
                handler.sendMessage(msg);// Send notification to change UI
            }
        });

    } catch (NumberFormatException e) {
        e.printStackTrace();
        NumberRunningTextView.this.setText(moneyStr);//If conversion Double fails, use setText directly
    }
}

1. Modify the incoming string first. If there are commas or minus signs, remove commas and minus signs.

2. Format the string. If the conversion is abnormal, call setText() method directly to set the content.

3. If the number passed in is 0, setText() is invoked directly to set the content without scrolling animation.

4. If the correct amount of money is passed in, divide the number of frames by frameNum to get the size of each frame (interval). By using sendMessage of handler, the type of current content and the size of each frame are transmitted, and the handleMessage () method of handler is processed accordingly. The threadPool is a thread pool with one thread. ThreadPool = Executors. new Fixed ThreadPool (1);

The corresponding processing in Handler:

 private Handler handler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);
        switch (msg.what) {
            case MONEY_TYPE://The rolling of money figures
                String str = formatter.format(nowMoneyNum).toString();//Keep two decimal strings

                // Update the display
                if (useCommaFormat) {
                    //Use a comma format for every three digits
                    String formatStr = StringUtils.addComma(str);//Three comma-formatted strings
                    NumberRunningTextView.this.setText(formatStr);
                } else {
                    NumberRunningTextView.this.setText(str);
                }

                nowMoneyNum += (double) msg.obj;//Record the current incremental number per frame

                if (nowMoneyNum < finalMoneyNum) {
                    //If the current recorded amount is less than the target amount, that is, the target amount has not yet been reached, continue to increase.
                    Message msg2 = handler.obtainMessage();
                    msg2.what = MONEY_TYPE;
                    msg2.obj = msg.obj;
                    handler.sendMessage(msg2);// Continue sending notifications to change UI
                } else {
                    //Number of amounts that have been achieved, showing the final number
                    if (useCommaFormat) {
                        NumberRunningTextView.this.setText(StringUtils.addComma(formatter.format(finalMoneyNum)));
                    } else {
                        NumberRunningTextView.this.setText(formatter.format(finalMoneyNum));
                    }
                }
                break;

            case NUM_TYPE://Ordinary digital scrolling
                ...
                break;
        }
    }
};

In the handleMessage() method, the corresponding processing is performed according to the type of content.

1. Display the increased number of frames according to whether or not commas are used for formatting.

2. If it is less than the final MoneyNum target number (the final number), then continue to call the sendMessage() method to form a recursive operation until it is equal to or greater than the target number;

3. After reaching the target number, format the final result with commas according to whether or not it is necessary.

Where formatter = new DecimalFormat("0.00"); and // formatted amount, retaining two decimal digits, used to make double type digits retain two decimal digits.

_To this point, the specific design ideas should be clear, in fact, by using handler to send messages continuously, form recursion, let the number increase, when the final number is reached, stop sending messages, directly set the final content. playNumAnim() is the same idea. I will not repeat it here. I feel that my comments are enough detailed. By the way, I will paste the method of playNumAnim().

/**
 * Method of Playing Digital Animation
 *
 * @param numStr
 */
public void playNumAnim(String numStr) {
    String num = numStr.replace(",", "").replace("-", "");//If the incoming number has been formatted using commas or contains symbols, remove commas and minus signs
    try {
        finalNum = Integer.parseInt(num);
        if (finalNum < frameNum) {
            //Since it is an integer, incrementing by 1 at a time, if the number of incoming frames is smaller than the number of frames, setText() is used directly.
            NumberRunningTextView.this.setText(numStr);
            return;
        }
        nowNum = 0;// By default, animation starts at 0.
        threadPool.execute(new Runnable() {
            @Override
            public void run() {
                Message msg = handler.obtainMessage();
                int temp = finalNum / frameNum;//Divide the number of frames to get the hop size of each frame
                msg.what = NUM_TYPE;
                msg.obj = temp;
                handler.sendMessage(msg);// Send notification to change UI
            }
        });

    } catch (NumberFormatException e) {
        e.printStackTrace();
        NumberRunningTextView.this.setText(numStr);//If conversion Double fails, use setText directly
    }
}

The corresponding processing in handler:

 private Handler handler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);
        switch (msg.what) {
            case MONEY_TYPE://The rolling of money figures
                ...
                break;

            case NUM_TYPE://Ordinary digital scrolling
                NumberRunningTextView.this.setText(String.valueOf(nowNum));
                nowNum += (Integer) msg.obj;//Record the current incremental number per frame
                if (nowNum < finalNum) {
                    //If the current recorded number is less than the target number, that is, if the target number has not been reached, continue to increase.
                    Message msg2 = handler.obtainMessage();
                    msg2.what = NUM_TYPE;
                    msg2.obj = msg.obj;
                    handler.sendMessage(msg2);// Continue sending notifications to change UI
                } else {
                    //Numbers that have reached their goals, showing the final content
                    NumberRunningTextView.this.setText(String.valueOf(finalNum));
                }
                break;
        }
    }
};

So far, the introduction of NumberRunning TextView and source code parsing are over. Here's how to import the control

Import mode

In all projects {} in build.gradle under the project root directory, add the jitpack warehouse address as follows:

allprojects {
    repositories {
        jcenter()
        maven { url 'https://jitpack.io'}// Add jitpack warehouse address
    }
}

Open build.gradle in the module of app and add dependencies in dependencies {} as follows:

dependencies {
        ......
        compile 'com.github.chaychan:PowerfulViewLibrary:1.1.0'
}

Source github address: https://github.com/chaychan/PowerfulViewLibrary.git

It still took me half a day to complete my fourth blog. Last time I wrote a blog on March 8th, I always wanted to write more blogs, but I intuitively had to write high-quality blogs if I wanted to write, although it took a long time, because I wrote articles in the pursuit of clarity, easy to understand, so that readers do not feel confused, pursuing quality rather than quantity. Writing a blog should also have good subject matter, think of which knowledge point is more interesting to readers and can help readers to develop their daily life. This Number Running TextView is written when doing the project, when displaying the balance of users, according to the needs of the digital scrolling effect, so I went online to find ideas and write by myself. With such a View, I think many people will need it. I hope it can help you.

Keywords: Android less github Gradle

Added by mickeyunderscore on Tue, 09 Jul 2019 01:17:49 +0300