3 回答

TA貢獻(xiàn)1785條經(jīng)驗(yàn) 獲得超8個(gè)贊
下面是一個(gè)示例,說(shuō)明如何使用 的postDelayed()方法Handler創(chuàng)建倒計(jì)時(shí)。我特意把代碼留得有點(diǎn)冗長(zhǎng),這樣你就可以一步一步地瀏覽它,看看發(fā)生了什么。
創(chuàng)建一些類變量和常量。
private static final long COUNT_DOWN_TICKS = 100l;
private static final long COUNT_DOWN_FINISH = 5000l;
private long countdownElapsed = 0l;
private Handler mCountDownHandler = new Handler();
COUNT_DOWN_FINISH設(shè)置為 5000 --> 5 秒。但可以更改為您需要的任何內(nèi)容。我還使用COUNT_DOWN_TICKSset 為 100 --> 0.1 秒,以防萬(wàn)一您想顯示更精確的倒計(jì)時(shí)。
從您的OnClick()方法中只需調(diào)用startCountDown()即可開始倒計(jì)時(shí)。
private void startCountDown() {
try {
countdownElapsed = 0l;
next_button.setEnabled(false);
displayCountDown();
mCountDownHandler.postDelayed(mCountDownRunnable, COUNT_DOWN_TICKS);
}
catch (Exception ex){
Log.e(TAG, ex.getMessage());
}
}
private Runnable mCountDownRunnable = new Runnable() {
@Override
public void run() {
countdownElapsed = countdownElapsed + COUNT_DOWN_TICKS;
if(countdownElapsed >= COUNT_DOWN_FINISH){
releaseCountDownHandler();
next_button.setEnabled(true);
}
else{
mCountDownHandler.postDelayed(mCountDownRunnable, COUNT_DOWN_TICKS);
}
long secFull = countdownElapsed % 1000;
if(secFull == 0){
runOnUiThread(new Runnable() {
@Override
public void run() {
displayCountDown();
}
});
}
}
};
private void releaseCountDownHandler() {
try {
if(mCountDownRunnable != null) {
mCountDownHandler.removeCallbacks(mCountDownRunnable);
}
}
catch (Exception ex){
Log.e(TAG, ex.getMessage());
}
}
private void displayCountDown(){
long t = (COUNT_DOWN_FINISH - countdownElapsed)/1000;
String myTime = String.valueOf(t);
timer.setText(myTime);
}
為了Runnable正確處理,您需要releaseCountDownHandler()從onPause()方法中調(diào)用。這只是一個(gè)短暫的運(yùn)行Thread,但它仍然不應(yīng)該被忽視。
我更喜歡HandlerwithpostDelay()方法而不是Thread.sleep()方法——讓任何線程進(jìn)入睡眠狀態(tài)的事情令人不安。另請(qǐng)注意,習(xí)慣于使用“>=”而不是“==”檢查經(jīng)過時(shí)間條件是個(gè)好主意,具體取決于實(shí)現(xiàn)(例如,您SystemClock.elapsedRealtime()改為使用)條件可能會(huì)錯(cuò)過確切的值!
編輯
在您的Activity類定義下的某處(在本例中,我將稱之為MainActivity)您需要聲明一些變量。由于它們是在類內(nèi)部而不是在方法內(nèi)部定義的,因此它們被稱為“類變量”,并且在定義為“私有”時(shí)具有整個(gè)類的范圍。
public class MainActivity extends AppCompatActivity {
//class variables
private static final long COUNT_DOWN_TICKS = 100l;
private static final long COUNT_DOWN_FINISH = 5000l;
private long countdownElapsed = 0l;
private Handler mCountDownHandler = new Handler();
private Button next_button;
private TextView timer;
....
}
您可能已經(jīng)在類onClick()的onCreate()方法中聲明了該方法MainActivity。所以只需添加以下代碼:
next_button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startCountDown();
}
我提供的所有其他方法都是MainActivity類中的方法……而不是任何其他方法中的方法。所以在onCreate()方法下面添加我之前發(fā)布的所有方法。
它看起來(lái)像這樣:
public class MainActivity extends AppCompatActivity {
private static final String TAG = MainActivity.class.getSimpleName();
//class variables
private static final long COUNT_DOWN_TICKS = 100l;
private static final long COUNT_DOWN_FINISH = 5000l;
private long countdownElapsed = 0l;
private Handler mCountDownHandler = new Handler();
private Button next_button;
private TextView timer;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// you must compensate for the actual layout for your activity
setContentView(R.layout.activity_main);
// you must compensate for the actual id of the TextView
timer = findViewById(R.id.tvTimer);
// you must compensate for the actual id of the Button
next_button = findViewById(R.id.btnNext);
next_button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startCountDown();
}
});
}
private void startCountDown() {
try {
countdownElapsed = 0l;
next_button.setEnabled(false);
displayCountDown();
mCountDownHandler.postDelayed(mCountDownRunnable, COUNT_DOWN_TICKS);
}
catch (Exception ex){
Log.e(TAG, ex.getMessage());
}
}
private Runnable mCountDownRunnable = new Runnable() {
@Override
public void run() {
countdownElapsed = countdownElapsed + COUNT_DOWN_TICKS;
if(countdownElapsed >= COUNT_DOWN_FINISH){
releaseCountDownHandler();
next_button.setEnabled(true);
}
else{
mCountDownHandler.postDelayed(mCountDownRunnable, COUNT_DOWN_TICKS);
}
long secFull = countdownElapsed % 1000;
if(secFull == 0){
runOnUiThread(new Runnable() {
@Override
public void run() {
displayCountDown();
}
});
}
}
};
private void releaseCountDownHandler() {
try {
if(mCountDownRunnable != null) {
mCountDownHandler.removeCallbacks(mCountDownRunnable);
}
}
catch (Exception ex){
Log.e(TAG, ex.getMessage());
}
}
private void displayCountDown(){
long t = (COUNT_DOWN_FINISH - countdownElapsed)/1000;
String myTime = String.valueOf(t);
timer.setText(myTime);
}
}

TA貢獻(xiàn)1775條經(jīng)驗(yàn) 獲得超11個(gè)贊
這段代碼就像我上面的代碼,除了這段代碼引入了一個(gè)“點(diǎn)擊計(jì)數(shù)器”。我引入了一個(gè)新的類變量來(lái)跟蹤按鈕被點(diǎn)擊的次數(shù)。我還引入了一個(gè)名為“NUMBER_OF_BUTTON_CLICKS”的新常量,它作為點(diǎn)擊次數(shù)的上限。
用戶現(xiàn)在可以點(diǎn)擊按鈕(在本例中)5 次。第 5 次單擊時(shí),滿足觸發(fā)startCountDown方法的條件并且按鈕被禁用 5 秒。
public class MainActivity extends AppCompatActivity {
//Constant values
private static final String TAG = MainActivity.class.getSimpleName();
private static final int NUMBER_OF_BUTTON_CLICKS = 5;
private static final long COUNT_DOWN_TICKS = 100l;
private static final long COUNT_DOWN_FINISH = 5000l;
//class variables
private int howManyClicks = 0;
private long countdownElapsed = 0l;
private Handler mCountDownHandler = new Handler();
private Button next_button;
private TextView timer;
private TextView clicks;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// you must compensate for the actual layout for your activity
setContentView(R.layout.activity_main);
// you must compensate for the actual id of the TextView
timer = findViewById(R.id.tvTimer);
// Use this only if you want to display the number of clicks
// you might need to add this TextView if you want to display the number of clicks
clicks = findViewById(R.id.tvClicks);
// you must compensate for the actual id of the Button
next_button = findViewById(R.id.btnNext);
next_button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
howManyClicks++;
if(howManyClicks >= NUMBER_OF_BUTTON_CLICKS){
startCountDown();
}
//Add this only if you want to see how many clicks were made
String myClicks = String.valueOf(howManyClicks);
clicks.setText(myClicks)
}
});
}
private void startCountDown() {
try {
countdownElapsed = 0l;
next_button.setEnabled(false);
displayCountDown();
mCountDownHandler.postDelayed(mCountDownRunnable, COUNT_DOWN_TICKS);
}
catch (Exception ex){
Log.e(TAG, ex.getMessage());
}
}
private Runnable mCountDownRunnable = new Runnable() {
@Override
public void run() {
countdownElapsed = countdownElapsed + COUNT_DOWN_TICKS;
if(countdownElapsed >= COUNT_DOWN_FINISH){
releaseCountDownHandler();
next_button.setEnabled(true);
// reset the clicks counter
howManyClicks = 0;
}
else{
mCountDownHandler.postDelayed(mCountDownRunnable, COUNT_DOWN_TICKS);
}
long secFull = countdownElapsed % 1000;
if(secFull == 0){
runOnUiThread(new Runnable() {
@Override
public void run() {
displayCountDown();
}
});
}
}
};
private void releaseCountDownHandler() {
try {
if(mCountDownRunnable != null) {
mCountDownHandler.removeCallbacks(mCountDownRunnable);
}
}
catch (Exception ex){
Log.e(TAG, ex.getMessage());
}
}
private void displayCountDown(){
long t = (COUNT_DOWN_FINISH - countdownElapsed)/1000;
String myTime = String.valueOf(t);
timer.setText(myTime);
//Add this only if you want to see how many clicks were made
String myClicks = String.valueOf(howManyClicks);
clicks.setText(myClicks)
}
}
添加回答
舉報(bào)