Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android 關於倒計時功能的說說

Android 關於倒計時功能的說說

編輯:關於Android編程

 關於倒計時的實現,可以說有很多的方法,比較常見的就是Timer+TimerTask+Handler了,或者還可以配合Runnable。例如下面的代碼:   [html]   import java.util.Timer;   import java.util.TimerTask;   import android.app.Activity;   import android.os.Bundle;   import android.os.Handler;   import android.os.Message;   import android.util.Log;   import android.view.View;   import android.widget.Button;   import android.widget.TextView;      public class MainActivity extends Activity {          Timer timer;              @Override       public void onCreate(Bundle savedInstanceState) {           super.onCreate(savedInstanceState);           setContentView(R.layout.main);              final TextView tv = (TextView) findViewById(R.id.textView1);           Button b = (Button) findViewById(R.id.button1);              // 定義Handler           final Handler handler = new Handler() {                  @Override               public void handleMessage(Message msg) {                   super.handleMessage(msg);                   //handler處理消息                   if(msg.what>0){                       tv1.setText("" + msg.what);                   }else{                       //在handler裡可以更改UI組件                       tv.setText("倒時");                       timer.cancel();                   }               }           };              b.setOnClickListener(new View.OnClickListener() {                  @Override               public void onClick(View arg0) {                   // 定義計時器                    timer = new Timer();                      // 定義計劃任務,根據參數的不同可以完成以下種類的工作:在固定時間執行某任務,在固定時間開始重復執行某任務,重復時間間隔可控,在延遲多久後執行某任務,在延遲多久後重復執行某任務,重復時間間隔可控                   timer.schedule(new TimerTask() {                       int i = 10;                          // TimerTask 是個抽象類,實現的是Runable類                       @Override                       public void run() {                                                      //定義一個消息傳過去                           Message msg = new Message();                           msg.what = i--;                           handler.sendMessage(msg);                       }                      }, 1000, 200);               }           });          }      }       基本邏輯就是這樣,需要注意一點是 timer.schedule(task,1000,5000),如果設置為 timer.schedule(task,5000)是不會工作的。因為timer.schedule(task,5000) 是表示執行一次的任務。timer.schedule(task,1000,5000)表示1 秒鐘後開始 5 秒鐘為周期 的重復執行任務。顯然,這個方式比較笨拙,我們可以對此進行一個封裝,利用Handler和Eunnable,看下面的代碼: [html]   package com.example.daojishi;      import android.os.Handler;   import android.util.Log;      public class MyCountDownTimer {       private long millisInFuture;       private long countDownInterval;       private boolean status;          public MyCountDownTimer(long pMillisInFuture, long pCountDownInterval) {           this.millisInFuture = pMillisInFuture;           this.countDownInterval = pCountDownInterval;           status = false;           Initialize();       }          public void Stop() {           status = false;       }          public long getCurrentTime() {           return millisInFuture;       }          public void Start() {           status = true;       }          public void Initialize() {           final Handler handler = new Handler();           Log.v("status", "starting");           final Runnable counter = new Runnable() {                  public void run() {                   long sec = millisInFuture / 1000;                   if (status) {                       if (millisInFuture <= 0) {                           Log.v("status", "done");                       } else {                           Log.v("status", Long.toString(sec) + " seconds remain");                           millisInFuture -= countDownInterval;                           handler.postDelayed(this, countDownInterval);                       }                   } else {                       Log.v("status", Long.toString(sec)                               + " seconds remain and timer has stopped!");                       handler.postDelayed(this, countDownInterval);                   }               }           };              handler.postDelayed(counter, countDownInterval);       }   }       這個類就是負責倒計時的類,下面結合Activity,看一下怎麼用: [html]  package com.example.daojishi;      import android.app.Activity;   import android.os.Bundle;   import android.os.Handler;   import android.util.Log;   import android.view.View;   import android.widget.Button;   import android.widget.TextView;      public class CounterActivity extends Activity {       /** Called when the activity is first created. */       TextView timeText;       Button startBut;       Button stopBut;       MyCountDownTimer mycounter;          @Override       public void onCreate(Bundle savedInstanceState) {           super.onCreate(savedInstanceState);           setContentView(R.layout.main);           timeText = (TextView) findViewById(R.id.time);           startBut = (Button) findViewById(R.id.start);           stopBut = (Button) findViewById(R.id.stop);           mycounter = new MyCountDownTimer(20000, 1000);           RefreshTimer();       }          public void StartTimer(View v) {           Log.v("startbutton", "開始倒計時");           mycounter.Start();       }          public void StopTimer(View v) {           Log.v("stopbutton", "暫停倒計時");           mycounter.Stop();       }          public void RefreshTimer() {           final Handler handler = new Handler();           final Runnable counter = new Runnable() {                  public void run() {                   timeText.setText(Long.toString(mycounter.getCurrentTime()));                   handler.postDelayed(this, 100);               }           };              handler.postDelayed(counter, 100);       }   }       布局文件: [html]   <?xml version="1.0" encoding="utf-8"?>   <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"       android:layout_width="fill_parent"       android:layout_height="fill_parent"       android:orientation="vertical"       android:weightSum="1" >          <TextView           android:id="@+id/time"           android:layout_width="wrap_content"           android:layout_height="wrap_content"           android:text="TextView"           android:textAppearance="?android:attr/textAppearanceLarge" >       </TextView>          <Button           android:id="@+id/start"           android:layout_width="wrap_content"           android:layout_height="wrap_content"           android:onClick="StartTimer"           android:text="Start" >       </Button>          <Button           android:id="@+id/stop"           android:layout_width="wrap_content"           android:layout_height="wrap_content"           android:onClick="StopTimer"           android:text="Stop" >       </Button>      </LinearLayout>       這樣就可以比較方便地使用倒計時功能了。但是還有一個更簡單的方法。     在Android中有一個CountDownTimer類,這個類就是用來實現類似倒計時方面的功能。使用的時候,只需要繼承自CountDownTimer並實現它的方法。          [html]  import android.app.Activity;     import android.os.Bundle;     import android.content.Intent;     import android.os.CountDownTimer;     import android.widget.TextView;     import android.widget.Toast;     public class NewActivity extends Activity {         private MyCount mc;         private TextView tv;         @Override         protected void onCreate(Bundle savedInstanceState) {                 super.onCreate(savedInstanceState);             setContentView(R.layout.main);             tv = (TextView)findViewById(R.id.show);             mc = new MyCount(30000, 1000);             mc.start();         }             /*定義一個倒計時的內部類*/         class MyCount extends CountDownTimer {                public MyCount(long millisInFuture, long countDownInterval) {                    super(millisInFuture, countDownInterval);                }                @Override                public void onFinish() {                    tv.setText("done");                   }                @Override                public void onTick(long millisUntilFinished) {                    tv.setText("seconds remaining: " + millisUntilFinished / 1000);                              }           }        }         onFinish()方法是本次倒計時結束的時候調用的,onTick是每隔1秒鐘執行的,我們就是在這裡執行重復的任務,像本例子的顯示時間。執行完後會自動取消,如果在期間停止的話,可以調用cancel()方法。看一下它的源碼就會發現,它是使用Handler+SystemClock來實現的。 [html]  /*    * Copyright (C) 2008 The Android Open Source Project    *    * Licensed under the Apache License, Version 2.0 (the "License");    * you may not use this file except in compliance with the License.    * You may obtain a copy of the License at    *    *      http://www.apache.org/licenses/LICENSE-2.0    *    * Unless required by applicable law or agreed to in writing, software    * distributed under the License is distributed on an "AS IS" BASIS,    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.    * See the License for the specific language governing permissions and    * limitations under the License.    */      package android.os;      import android.util.Log;      /**    * Schedule a countdown until a time in the future, with    * regular notifications on intervals along the way.    *    * Example of showing a 30 second countdown in a text field:    *    * <pre class="prettyprint">    * new CountDownTimer(30000, 1000) {    *    *     public void onTick(long millisUntilFinished) {    *         mTextField.setText("seconds remaining: " + millisUntilFinished / 1000);    *     }    *    *     public void onFinish() {    *         mTextField.setText("done!");    *     }    *  }.start();    * </pre>    *    * The calls to {@link #onTick(long)} are synchronized to this object so that    * one call to {@link #onTick(long)} won't ever occur before the previous    * callback is complete.  This is only relevant when the implementation of    * {@link #onTick(long)} takes an amount of time to execute that is significant    * compared to the countdown interval.    */   public abstract class CountDownTimer {          /**        * Millis since epoch when alarm should stop.        */       private final long mMillisInFuture;          /**        * The interval in millis that the user receives callbacks        */       private final long mCountdownInterval;          private long mStopTimeInFuture;          /**        * @param millisInFuture The number of millis in the future from the call        *   to {@link #start()} until the countdown is done and {@link #onFinish()}        *   is called.        * @param countDownInterval The interval along the way to receive        *   {@link #onTick(long)} callbacks.        */       public CountDownTimer(long millisInFuture, long countDownInterval) {           mMillisInFuture = millisInFuture;           mCountdownInterval = countDownInterval;       }          /**        * Cancel the countdown.        */       public final void cancel() {           mHandler.removeMessages(MSG);       }          /**        * Start the countdown.        */       public synchronized final CountDownTimer start() {           if (mMillisInFuture <= 0) {               onFinish();               return this;           }           mStopTimeInFuture = SystemClock.elapsedRealtime() + mMillisInFuture;           mHandler.sendMessage(mHandler.obtainMessage(MSG));           return this;       }             /**        * Callback fired on regular interval.        * @param millisUntilFinished The amount of time until finished.        */       public abstract void onTick(long millisUntilFinished);          /**        * Callback fired when the time is up.        */       public abstract void onFinish();             private static final int MSG = 1;             // handles counting down       private Handler mHandler = new Handler() {              @Override           public void handleMessage(Message msg) {                  synchronized (CountDownTimer.this) {                   final long millisLeft = mStopTimeInFuture - SystemClock.elapsedRealtime();                      if (millisLeft <= 0) {                       onFinish();                   } else if (millisLeft < mCountdownInterval) {                       // no tick, just delay until done                       sendMessageDelayed(obtainMessage(MSG), millisLeft);                   } else {                       long lastTickStart = SystemClock.elapsedRealtime();                       onTick(millisLeft);                          // take into account user's onTick taking time to execute                       long delay = lastTickStart + mCountdownInterval - SystemClock.elapsedRealtime();                          // special case: user's onTick took more than interval to                       // complete, skip to next interval                       while (delay < 0) delay += mCountdownInterval;                          sendMessageDelayed(obtainMessage(MSG), delay);                   }               }           }       };   }       所以,如果你的程序需要執行一些周期性的任務,就可以考慮使用CountDownTimer這個類了。需要注意的是,在上面的這個例子中,最後顯示時間是1,也就是說其實上執行了29次。所以這個地方一定要注意,如果你的任務次數是n,那麼設置的時候一定要注意設置成n+1的時間。
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved