2009-02-07 13 views
17

Pour mon application Android, il y a une minuterie qui mesure combien de temps s'est écoulé. Toujours 100 millisecondes je met à jour mon TextView avec du texte comme "Score: 10 temps: 100.10 secondes". Mais, je trouve que le TextView ne met à jour que les premières fois. L'application est toujours très réactive, mais l'étiquette ne sera pas mise à jour. J'ai essayé d'appeler .invalidate(), mais cela ne fonctionne toujours pas. Je ne sais pas s'il existe un moyen de résoudre ce problème, ou un meilleur widget à utiliser.Android TextView Minuterie

Voici un exemple de mon code:

float seconds; 
java.util.Timer gametimer; 
void updatecount() { TextView t = (TextView)findViewById(R.id.topscore); 
t.setText("Score: 10 - Time: "+seconds+" seconds"); 
t.postInvalidate(); 
} 
public void onCreate(Bundle sis) { 
... Load the UI, etc... 
    gametimer.schedule(new TimerTask() { public void run() { 
    seconds+=0.1; updatecount(); 
} }, 100, 100); 
} 

Répondre

18

La solution générale est d'utiliser à la place android.os.Handler qui court dans le thread d'interface utilisateur. Il ne fait que des rappels ponctuels, vous devez donc le déclencher à nouveau chaque fois que votre rappel est appelé. Mais c'est assez facile à utiliser. Un billet de blog sur ce sujet a été écrit il y a quelques années:

http://android-developers.blogspot.com/2007/11/stitch-in-time.html

+0

Merci pour ce lien. Le code sur cette page a parfaitement fonctionné avec ma minuterie basée sur TextView. – RyanM

2

Ce que je pense qui se passe est vous tomber du thread d'interface utilisateur. Il y a un seul thread "looper" qui gère toutes les mises à jour de l'écran. Si vous essayez d'appeler "invalidate()" et que vous n'êtes pas sur ce thread, rien ne se passera.

Essayez d'utiliser "postInvalidate()" sur votre vue à la place. Il vous permettra de mettre à jour une vue lorsque vous n'êtes pas dans le thread d'interface utilisateur actuel.

Plus d'info here

+0

Cela ne fonctionne toujours pas - il est mis à jour la première fois, donc je sais que cela fonctionne, mais ne met pas à jour par la suite. Merci quand même, Isaac. –

+0

si vous voulez poster un code snippit je vais jeter un coup d'oeil – haseman

+0

J'ai ajouté un exemple de code à mon message - merci! –

0

utilisation ci-dessous le code pour régler l'heure sur TextView

public class MyCountDownTimer extends CountDownTimer { 
     public MyCountDownTimer(long startTime, long interval) { 
      super(startTime, interval); 
     } 

     @Override 
     public void onFinish() { 

      ExamActivity.this.submitresult(); 
     } 

     @Override 
     public void onTick(long millisUntilFinished) { 

      long millis = millisUntilFinished; 

      int seconds = (int) (millis/1000) % 60; 
      int minutes = (int) ((millis/(1000 * 60)) % 60); 
      int hours = (int) ((millis/(1000 * 60`enter code here` * 60)) % 24); 

      String ms = String 
        .format("%02d:%02d:%02d", hours, minutes, seconds); 
      txtimedisplay.setText(ms); 
     } 
    } 
0

Il y a une autre façon de modifier le texte de chaque seconde; c'est ValueAnimator. Voici ma solution:

long startTime = System.currentTimeMillis(); 
    ValueAnimator animator = new ValueAnimator(); 
      animator.setObjectValues(0, 1000); 
      animator.setDuration(1000); 
      animator.setRepeatCount(ValueAnimator.INFINITE); 
      animator.addListener(new AnimatorListenerAdapter() { 

       @Override 
       public void onAnimationStart(Animator animation) { 
        long currentTime = System.currentTimeMillis(); 
        String text = TimeFormatUtils.formatTime(startTime - currentTime); 
        yourTextView.setText(text); 
       } 

       @Override 
       public void onAnimationRepeat(Animator animation) { 
        long currentTime = System.currentTimeMillis(); 
        String text = TimeFormatUtils.formatTime(startTime - currentTime); 
        yourTextView.setText(text); 
       } 
      }); 
      animator.start();