標籤:animator extend 判斷 次數 XML padding 控制 cal .com
某些app上,新進入一個Activity的時候,上面的一個關鍵性數字(比如金額)會以一個數字不斷變大的動畫來顯示。剛開始的時候,想到的一個方案是:使用Thead+Handler,給定一個動畫總時間長度與重新整理間隔時間長度,根據公式(數字從0開始,每次增長值為數組除以動畫執行次數,動畫執行次數等於動畫總時間長度除以重新整理間隔時間長度);
每隔一段時間重新設定TextView的字串為增加後的值,直到動畫結束顯示最終結果。
其實對安卓動畫有一定瞭解的應該都知道ValueAnimator這個類,我們可以使用它來很好的實現所要的效果,而不需要我們自己來生硬的控制隔多久就增加多少重新整理顯示。根據ValueAnimator的屬性方法以及實際需要,我們封裝一個自訂View來實現我們的需求。
先看一下我實現的
接下來上關鍵代碼:
自訂View,其實就是繼承一個TextView,代碼實現很簡單,代碼中也有注釋
/** * Created by dingchao on 2018/3/27. */public class DcTextViewRunNumber extends TextView { /** * 延遲 */ private final int DELAY = 20; /** * 保留小數位元 預設2為 */ private final int DECIMALS_COUNT = 2; private final int START_RUN = 101; private final int STOP_RUN = 102; /** * 跑的次數 */ private final int RUN_COUNT = 40; private float speed; private float startNum; private float endNum; /** * 保留小數位元 */ private int decimals = DECIMALS_COUNT; /** * 每次跑的次數 */ private int runCount = RUN_COUNT; /** * 動畫延遲 */ private int delayMillis = DELAY; private boolean isAniming; private Handler mHandler = new Handler() { public void handleMessage(Message msg) { if (msg.what == START_RUN) { if(speed==0){ if(endNum!=0){ speed = getSpeed(); startNum = speed; }else{ return ; } } isAniming = !running(); if (isAniming) { sendEmptyMessageDelayed(START_RUN, delayMillis); }else{ speed = 0; startNum = 0; } } }; }; public DcTextViewRunNumber(Context context) { super(context); } public DcTextViewRunNumber(Context context, AttributeSet attrs) { super(context, attrs); } public DcTextViewRunNumber(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } /** * 開始數字跳動動畫 * @return 動畫是否結束 */ private boolean running() { setText(withDEC(String.valueOf(startNum)) + ""); startNum +=speed; if(startNum >= endNum){ setText(withDEC(String.valueOf(endNum)) + ""); return true; } return false; } /** * 計算速度 * @return */ private float getSpeed(){ float speedFloat = withDEC(String.valueOf(endNum/runCount)).floatValue(); return speedFloat; } /** * 判斷是否是非負數 * @return */ private boolean isNumber(String num){ if("".equals(num) || num==null) return false; Pattern pattern = Pattern.compile("^\\d+$|\\d+\\.\\d+$"); Matcher matcher = pattern.matcher(num); return matcher.find(); } /** * 取整四捨五入 保留小數 * @param num * @return */ private BigDecimal withDEC(String num){ return new BigDecimal(num).setScale(decimals, BigDecimal.ROUND_HALF_UP); } /** * 設定顯示的數字 * @param num */ public void setShowNum(String num){ setShowNum(num,DECIMALS_COUNT); } /** * 設定顯示的數字 * @param num * @param decimals 要保留的小數位 */ public void setShowNum(String num,int decimals){ if(!isNumber(num)){ return; } setText(num); setDecimals(decimals); } /** * 開始跑 */ public void startRun(){ if(isAniming){ return ; } if(isNumber(getText().toString())){ endNum = withDEC(getText().toString()).floatValue(); mHandler.sendEmptyMessage(START_RUN); } } public int getDecimals() { return decimals; } /** * 設定保留的小數位 0:不保留小數 * @param decimals */ public void setDecimals(int decimals) { if(decimals>=0){ this.decimals = decimals; } setText(withDEC(getText().toString())+""); } public int getRunCount() { return runCount; } /** * 設定動畫跑的次數 * @param runCount */ public void setRunCount(int runCount) { if(runCount<=0){ return ; } this.runCount = runCount; } public int getDelayMillis() { return delayMillis; } /** * 設定動畫延遲 * @param delayMillis */ public void setDelayMillis(int delayMillis) { this.delayMillis = delayMillis; }
接下來看怎麼使用,MainActivity.java中
public class MainActivity extends AppCompatActivity { private DcTextViewRunNumber numberRunView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); numberRunView = (DcTextViewRunNumber) findViewById(R.id.numberRunView); numberRunView.setShowNum("711", 0);//終止的數字,小數點,這裡為0所以沒有小數點 numberRunView.setRunCount(50);//動畫執行的次數,50次執行完// numberRunView.setShowNum("221.918899"); numberRunView.startRun();// } /** * @param view */ public void runClick(View view) { numberRunView.startRun(); }}
activity_main.xml也貼一下吧,貼全了吧
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity"> <cn.up.com.textviewrun.DcTextViewRunNumber android:id="@+id/numberRunView" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="20dp" android:text="123" android:textSize="30sp" /> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="runClick" android:text="跑" /></LinearLayout>
主要的就是這三個檔案,代碼都全部貼出來了,效果也還可以。開發中不要重複造輪子,有的改一下就可以直接用咯。
Android TextView數字增長動畫效果