編輯:關於Android編程
今天我們自定義一個TextView,它的名稱叫做RiseNumberTextView,我們在平時使用支付寶的時候會發現進入資產頁面的時候,資產數據會從一個數一直不停的增長直至你的真實數據然後停止。
那麼這個效果是如何做到的呢?首先來看一下我們做出的效果圖,然後我們一起來實現它。
這裡面會用到一個核心的類:ValueAnimatr這是一個android屬性動畫
按照面向接口編程的好習慣,首先定義一個接口:
/** * 增長的數字接口 * */ public interface IRiseNumber { /** * 開始播放動畫的方法 */ public void start(); /** * 設置小數 * * @param number * @return */ public void withNumber(float number); /** * 設置整數 * * @param number * @return */ public void withNumber(int number); /** * 設置動畫播放時長 * * @param duration * @return */ public void setDuration(long duration); /** * 設置動畫結束監聽器 * * @param callback */ public void setOnEndListener(RiseNumberTextView.EndListener callback); }
然後自定義view------數字增長TextView,內容如下:
import android.content.Context; import android.util.AttributeSet; import android.widget.TextView; import com.bear.risenumber.R; import com.nineoldandroids.animation.ValueAnimator; import java.text.DecimalFormat; /** * 自定義RiseNumberTextView繼承TextView,並實現接口RiseNumberBase * */ public class RiseNumberTextView 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 long duration = 1500; /** * 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 }; /** * 構造方法 * * @param context */ public RiseNumberTextView(Context context) { super(context); } /** * 使用xml布局文件默認的被調用的構造方法 * * @param context * @param attr */ public RiseNumberTextView(Context context, AttributeSet attr) { super(context, attr); setTextColor(context.getResources().getColor(R.color.rise_number_text_color_red)); setTextSize(30); } public RiseNumberTextView(Context context, AttributeSet attr, int defStyle) { super(context, attr, defStyle); } /** * 判斷動畫是否正在播放 * * @return */ 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(); } } /** * 設置一個小數進來 */ @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; } } /** * 設置一個整數進來 */ @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; } } /** * 設置動畫播放時間 */ @Override public void setDuration(long duration) { this.duration = duration; } /** * 設置動畫結束監聽器 */ @Override public void setOnEndListener(EndListener callback) { mEndListener = callback; } /** * 定義動畫結束接口 * * */ public interface EndListener { /** * 當動畫播放結束時的回調方法 */ public void onEndFinish(); } }
import android.app.Activity; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.Toast; import com.bear.risenumber.views.RiseNumberTextView; import com.bear.risenumber.views.RiseNumberTextView.EndListener; public class MainActivity extends Activity { private RiseNumberTextView rnTextView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); setupViews(); } private void setupViews() { // 獲取到RiseNumberTextView對象 rnTextView = (RiseNumberTextView) findViewById(R.id.risenumber_textview); // 設置數據 rnTextView.withNumber(2666.50f); // 設置動畫播放時間 rnTextView.setDuration(5000); // 監聽動畫播放結束 rnTextView.setOnEndListener(new EndListener() { @Override public void onEndFinish() { Toast.makeText(MainActivity.this, "數據增長完畢...", Toast.LENGTH_SHORT).show(); } }); Button btn = (Button) findViewById(R.id.button1); btn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { if(rnTextView.isRunning()){ Toast.makeText(MainActivity.this, "數字還沒增長完,請稍候嘗試...", Toast.LENGTH_SHORT).show(); }else{ // 開始播放動畫 rnTextView.start(); } } }); } }
Android Rise Number TextView
本文使用Matrix實現Android實現圖片縮放與旋轉。示例代碼如下:復制代碼 代碼如下:package com.android.matrix;import andro
前言:多年之前接觸過zxing實現二維碼,沒想到今日項目中再此使用竟然使用的還是zxing,百度之,竟是如此牛的玩意。當然,項目中我們也許只會用到二維碼的掃描和生成兩個功
屏幕亮度自動調節:主要是從Sensor分析之中分離出來分析LIGHT 光線感應器,因此就分析一下自動調節屏幕亮度(手機隨著光線的強度自我調節,也就是在亮的光線下屏幕自動調
本篇文章講的是Android 自定義ViewGroup之實現標簽流式布局-FlowLayout,開發中我們會經常需要實現類似於熱門標簽等自動換行的流式布局的功能,網上也有