2009-02-07 21 views
17

Für meine Android-Anwendung gibt es einen Timer, der misst, wie viel Zeit vergangen ist. Immer 100 Millisekunden aktualisiere ich meine TextView mit etwas Text wie "Score: 10 Time: 100.10 Sekunden". Aber ich finde das TextView nur die ersten Male aktualisiert. Die Anwendung reagiert immer noch sehr gut, aber das Etikett wird nicht aktualisiert. Ich habe versucht, .invalidate() aufzurufen, aber es funktioniert immer noch nicht. Ich weiß nicht, ob es eine Möglichkeit gibt, das zu beheben oder ein besseres Widget zu verwenden. HierAndroid TextView Timer

ist ein Beispiel meines 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); 
} 

Antwort

18

Die allgemeine Lösung ist android.os.Handler stattdessen zu verwenden, die in dem UI-Thread ausgeführt wird. Es führt nur One-Shot-Callbacks aus, so dass Sie es jedes Mal erneut auslösen müssen, wenn Ihr Callback aufgerufen wird. Aber es ist einfach genug zu benutzen. Ein Blog-Post zu diesem Thema ein paar Jahren geschrieben wurde vor:

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

+0

Vielen Dank für diesen Link. Der Code auf dieser Seite funktionierte perfekt mit meinem TextView-basierten Timer. – RyanM

2

Was ich denke, passiert ist Sie fällt den UI-Thread ab. Es gibt einen einzelnen "Looper" -Thread, der alle Bildschirmaktualisierungen abwickelt. Wenn Sie versuchen, "invalidate()" aufzurufen, und Sie nicht in diesem Thread sind, wird nichts passieren.

Verwenden Sie stattdessen "postInvalidate()" in Ihrer Ansicht. Dadurch können Sie eine Ansicht aktualisieren, wenn Sie sich nicht im aktuellen UInthread befinden.

Mehr Infos here

+0

Es funktioniert immer noch nicht - es aktualisiert das erste Mal, so dass ich weiß, dass es funktioniert, aber nicht danach aktualisiert. Danke trotzdem, Isaac. –

+0

Wenn Sie einen Code snippit posten möchten, werde ich einen Blick – haseman

+0

werfen Ich habe einen Beispielcode zu meinem Beitrag hinzugefügt - danke! –

0

Verwenden Below Codezeit auf 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

Es gibt eine weitere Möglichkeit, Text jeder Sekunde zu setzen; Das ist ValueAnimator. Hier ist meine Lösung:

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();