專門顯示金錢文本 滾動顯示

Android 專門顯示金錢文本 滾動顯示

1.佈局中使用

  <com.project.aladdinslamp.view.NumberRollingView
            android:id="@+id/auw_income"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="0.00"
            android:textColor="@color/color_tv_orange"
            android:textSize="@dimen/sp_20"/>

2.控件代碼

public class NumberRollingView 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 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 NumberRollingView(Context context) {
        super(context);
    }

    public NumberRollingView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public NumberRollingView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.NumberRollingView);
        frameNum = ta.getInt(R.styleable.NumberRollingView_frameNum, 30);
        textType = ta.getInt(R.styleable.NumberRollingView_textType, MONEY_TYPE);
        useCommaFormat = ta.getBoolean(R.styleable.NumberRollingView_useCommaFormat, true);
        runWhenChange = ta.getBoolean(R.styleable.NumberRollingView_runWhenChange, true);
    }

    /**
     * @Description 幀數
     */
    public void setFrameNum(int frameNum) {
        this.frameNum = frameNum;
    }

    /**
     * @Description 內容的格式
     */
    public void setTextType(int textType) {
        this.textType = textType;
    }

    /**
     * @Description 是否設置每三位數字一個逗號
     */
    public void setUseCommaFormat(boolean useCommaFormat) {
        this.useCommaFormat = useCommaFormat;
    }

    /**
     * @Description 是否當內容改變的時候使用動畫,反之則不使用動畫
     */
    public void setRunWhenChange(boolean runWhenChange) {
        this.runWhenChange = runWhenChange;
    }

    /**
     * @Description 設置需要滾動的金錢(必須爲正數)或整數(必須爲正數)的字符串
     */
    public void setContent(String str) {
        //如果是當內容改變的時候才執行滾動動畫,判斷內容是否有變化
        if (runWhenChange) {
            if (TextUtils.isEmpty(preStr)) {
                //如果上一次的str爲空
                preStr = str;
                useAnimByType(str);
                return;
            }

            //如果上一次的str不爲空,判斷兩次內容是否一致
            if (preStr.equals(str)) {
                //如果兩次內容一致,則不做處理
                return;
            }

            //如果兩次內容不一致,記錄最新的str
            preStr = str;
        }
        useAnimByType(str);
    }

    private void useAnimByType(String str) {
        if (textType == MONEY_TYPE) {
            startMoneyAnim(str);
        } else {
            startNumAnim(str);
        }
    }

    /**
     * @Description 開始金額數字動畫的方法
     */
    public void startMoneyAnim(String moneyStr) {
        // 如果傳入的數字已經格式化了,則將包含的符號去除
        String money = moneyStr.replace(",", "").replace("-", "");
        try {
            finalMoneyNum = Double.parseDouble(money);
            if (finalMoneyNum == 0) {
                // 如果傳入的數字爲0則直接使用setText()進行顯示
                NumberRollingView.this.setText(moneyStr);
                return;
            }
            nowMoneyNum = 0;
            threadPool.execute(new Runnable() {
                @Override
                public void run() {
                    Message msg = handler.obtainMessage();
                    // 將傳入的數字除以幀數,得到每幀間隔的大小
                    double size = finalMoneyNum / frameNum;
                    msg.what = MONEY_TYPE;
                    // 如果每幀的間隔小於0.01,則設置間隔爲0.01
                    msg.obj = size < 0.01 ? 0.01 : size;
                    // 發送消息改變UI
                    handler.sendMessage(msg);
                }
            });
        } catch (NumberFormatException e) {
            e.printStackTrace();
            //如果轉換Double失敗則直接用setText()
            NumberRollingView.this.setText(moneyStr);
        }
    }

    /**
     * @Description 開始數字動畫的方法
     */
    public void startNumAnim(String numStr) {
        // 如果傳入的數字已經格式化了,則將包含的符號去除
        String num = numStr.replace(",", "").replace("-", "");
        try {
            finalNum = Integer.parseInt(num);
            if (finalNum < frameNum) {
                // 如果傳入的數字比幀數小,則直接使用setText()
                NumberRollingView.this.setText(numStr);
                return;
            }
            // 默認從0開始動畫
            nowNum = 0;
            threadPool.execute(new Runnable() {
                @Override
                public void run() {
                    Message msg = handler.obtainMessage();
                    // 將傳入的數字除以幀數,得到每幀間隔的大小
                    int temp = finalNum / frameNum;
                    msg.what = NUM_TYPE;
                    msg.obj = temp;
                    // 發送消息改變UI
                    handler.sendMessage(msg);
                }
            });
        } catch (NumberFormatException e) {
            e.printStackTrace();
            //如果轉換Integer失敗則直接用setText
            NumberRollingView.this.setText(numStr);
        }
    }

    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 = addComma(str, true);
                        NumberRollingView.this.setText(formatStr);
                    } else {
                        NumberRollingView.this.setText(str);
                    }

                    //記錄當前每幀遞增後的數字
                    nowMoneyNum += (double) msg.obj;

                    if (nowMoneyNum < finalMoneyNum) {
                        //如果當前記錄的金額數字小於目標金額數字,即還沒達到目標金額數字,繼續遞增
                        Message msg2 = handler.obtainMessage();
                        msg2.what = MONEY_TYPE;
                        msg2.obj = msg.obj;
                        // 繼續發送通知改變UI
                        handler.sendMessage(msg2);
                    } else {
                        //已經達到目標的金額數字,顯示最終的數字
                        if (useCommaFormat) {
                            NumberRollingView.this.setText(addComma(formatter.format(finalMoneyNum), true));
                        } else {
                            NumberRollingView.this.setText(formatter.format(finalMoneyNum));
                        }
                    }
                    break;
                case NUM_TYPE://普通數字滾動
                    // 更新顯示的內容
                    if (useCommaFormat) {
                        //使用每三位數字一個逗號格式的字符串
                        String formatStr = addComma(String.valueOf(nowNum), false);
                        NumberRollingView.this.setText(formatStr);
                    } else {
                        NumberRollingView.this.setText(String.valueOf(nowNum));
                    }

                    //記錄當前每幀遞增後的數字
                    nowNum += (Integer) msg.obj;
                    if (nowNum < finalNum) {
                        //如果當前記錄的數字小於目標數字,即還沒達到目標數字,繼續遞增
                        Message msg2 = handler.obtainMessage();
                        msg2.what = NUM_TYPE;
                        msg2.obj = msg.obj;
                        // 繼續發送通知改變UI
                        handler.sendMessage(msg2);
                    } else {
                        //已經達到目標的數字,顯示最終的內容
                        if (useCommaFormat) {
                            NumberRollingView.this.setText(addComma(String.valueOf(finalNum), false));
                        } else {
                            NumberRollingView.this.setText(String.valueOf(finalNum));
                        }
                    }
                    break;
            }
        }
    };

    /**
     * @param str       字符串只能爲兩位小數或者整數
     * @param isDecimal 是否是小數
     * @Description 格式化字符串,每三位用逗號隔開
     */
    public static String addComma(String str, boolean isDecimal) {
        //先將字符串顛倒順序
        str = new StringBuilder(str).reverse().toString();
        if (str.equals("0")) {
            return str;
        }
        String str2 = "";
        for (int i = 0; i < str.length(); i++) {
            if (i * 3 + 3 > str.length()) {
                str2 += str.substring(i * 3, str.length());
                break;
            }
            str2 += str.substring(i * 3, i * 3 + 3) + ",";
        }
        if (str2.endsWith(",")) {
            str2 = str2.substring(0, str2.length() - 1);
        }
        //最後再將順序反轉過來
        String temp = new StringBuilder(str2).reverse().toString();
        if (isDecimal) {
            //去掉最後的","
            return temp.substring(0, temp.lastIndexOf(",")) + temp.substring(temp.lastIndexOf(",") + 1, temp.length());
        } else {
            return temp;
        }
    }
}

3.JAVA代碼使用

//初始化
 income = (NumberRollingView) findViewById(R.id.auw_income);
        income.setUseCommaFormat(true);//設置每三位數字一個逗號
        income.setFrameNum(30);//設置幀數
        income.setRunWhenChange(false);//當內容相同的時候不使用動畫
//設置
income.setContent(mBalance);   //設置獲取的餘額
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章