2017-05-22 1 views
0

J'utilise CountDownTimer pour atteindre 5 secondes compte à rebours, ce qui suit est mon code:J'utilise CountDownTimer pour réaliser un compte à rebours de 5 secondes, mais le temps est mal, pourquoi?

public class CountDownTimerActivity extends AppCompatActivity { 

Button button; 
MyCountTimer timer; 
boolean isTick = false; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_count_down_timer); 

    timer = new MyCountTimer(5*1000,1000); 
    button = (Button)findViewById(R.id.countdown); 
    button.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View view) { 
      if (!isTick){ 
       timer.start(); 
       isTick = !isTick; 
      } 
     } 
    }); 
} 

class MyCountTimer extends CountDownTimer{ 

    public MyCountTimer(long millisInFuture, long countDownInterval) { 
     super(millisInFuture, countDownInterval); 
    } 

    @Override 
    public void onTick(long l) { 
     button.setText(l/1000+"秒"); 
    } 

    @Override 
    public void onFinish() { 
     button.setText("Sms Verification Code"); 
     isTick = false; 
    } 
} 

@Override 
protected void onDestroy() { 
    super.onDestroy(); 
    timer.cancel(); 
    isTick = false; 
} 

}

Mais je trouve un phénomène étrange, par exemple, je cliquez d'abord sur le bouton, il affiche 4,3 , 2,1 et parfois je clique de nouveau sur le bouton, peut-être 5,3,2,1 ou 5,4,2,1.Je ne connais pas la raison, je m'attendais à un résultat de 5,4,3,2, 1. Qui peut m'aider?

+0

Pourquoi avez-vous mis isTick = isTick si elle est déjà faux! Peut-être que je suis difficile mais cela semble étrange. En outre, le fait que vous utilisiez deux méthodes différentes pour définir isTick false ne facilite pas la lecture. – Phil3992

Répondre

0

Je suppose que le problème est avec

button.setText(l/1000+"秒"); 

Modifier à

int second = Math.round(l/1000f); 
button.setText(second +"秒"); 

S'il y a un certain retard ou les tiques fonctionnera trop tôt, vous obtiendrez l = 3999 et vous diviser pour 1000 vous sera Obtenez 3. C'est pourquoi vous avez des résultats étranges.

+0

J'essaie cela comme vous l'avez dit, mais le résultat devient 5,4,3,2 et le 1 est manquant –

0

J'ai utilisé Handler au lieu d'utiliser CountDownTimer pour atteindre le compte à rebours. Vous pouvez essayer comme ça

public class MainActivity extends AppCompatActivity { 

    private TextView label; 
    private Handler mTimerHandler; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     label = (TextView) findViewById(R.id.label); 

     findViewById(R.id.btnStartTimer).setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       mTimerHandler = new Handler(getMainLooper()); 
       mTimerHandler.postDelayed(new Timer(MainActivity.this, 5), 1000); 
      } 
     }); 
    } 

    @Override 
    protected void onDestroy() { 
     super.onDestroy(); 

     if (mTimerHandler != null) { 
      mTimerHandler.removeCallbacksAndMessages(null); 
      mTimerHandler = null; 
     } 
    } 

    private static class Timer implements Runnable { 

     int count = 1; 
     int max; 

     WeakReference<MainActivity> ui; 

     Timer(@NonNull MainActivity activity, int max) { 
      this.ui = new WeakReference<>(activity); 
      this.max = max; 
     } 

     @Override 
     public void run() { 
      if (count <= max) { 
       ui.get().label.setText(String.format("%s sec", count++)); 
       ui.get().mTimerHandler.postDelayed(this, 1000); 
      } else { 
       ui.get().label.setText("Sms verification completed."); 
       ui.get().mTimerHandler.removeCallbacks(this); 
      } 
     } 
    } 
} 
+0

oui, j'essaie, c'est ok. Mais je voudrais savoir le chemin de CountDownTimer pourquoi pas, où est le problème? –

+0

Vous pouvez vérifier [ceci] (https://stackoverflow.com/a/6811744/5447822) –

+0

J'essaie, et il fait 5,4,3,2 et 1 est manquant, mais je trouve une bonne idée, si vous voulez 5 secondes compte à rebours, vous devriez 'new CountDownTimer (5200,1000)', ça va, et il affichera 5,4,3,2,1 –

0

Je résolu ma question, parce que le CountDownTimer est inexact, il champ de tolérance est 1-10ms, donc si vous voulez 5 secondes Compte à rebours, vous pouvez ajouter à la 200ms millisInFuture. par exemple:

timer = new MyCountTimer(5200,1000); 

@Override 
public void onTick(long l) { 
    button.setText(l/1000+"second"); 
} 

il montrera 5,4,3,2,1