2010-02-19 3 views
88

Ho provato a fare questocome cambiare il testo in Android TextView

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    setContentView(R.layout.main); 

    t=new TextView(this); 

    t=(TextView)findViewById(R.id.TextView01); 
    t.setText("Step One: blast egg"); 

    try { 
     Thread.sleep(10000); 
    } catch (InterruptedException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 

    t.setText("Step Two: fry egg"); 

ma per qualche motivo, solo il secondo testo si presenta quando l'eseguo. Penso che potrebbe avere qualcosa a che fare con il blocco del metodo Thread.sleep(). Quindi qualcuno può mostrarmi come implementare un timer "in modo asincrono"?

Grazie.

+2

La ragione per cui mostra solo la seconda riga è perché '.setText()' sostituisce l'intero "widget" con il testo che gli dici di impostare; INCLUSO il testo che hai già inserito. – georgiaboy82

risposta

43

Ho appena pubblicato questa risposta nel gruppo Google Android-discutere

Se si sta solo cercando di aggiungere testo alla vista in modo che viene visualizzato "Fase uno: esplosione uovo Fase due: frittura di uova" Allora considerare l'utilizzo di t.appendText("Step Two: fry egg"); invece di t.setText("Step Two: fry egg");

Se si desidera cambiare completamente ciò che è nel TextView in modo che si dice "Fase uno: esplosione uovo" all'avvio e poi dice "Step Two: fry e gg" in un secondo momento si può sempre utilizzare un

esempio Runnable sadboy dato

Buona fortuna

14

La prima riga della nuova visualizzazione del testo è superflua

t=new TextView(this); 

si può semplicemente fare questo

TextView t = (TextView)findViewById(R.id.TextView01); 

quanto un thread in background che dorme qui è un esempio, ma penso che ci sia un timer che sarebbe meglio per questo. ecco un link per un buon esempio utilizzando un timer, invece http://android-developers.blogspot.com/2007/11/stitch-in-time.html

Thread thr = new Thread(mTask); 
    thr.start(); 
} 

Runnable mTask = new Runnable() { 
    public void run() { 
     // just sleep for 30 seconds. 
        try { 
         Thread.sleep(3000); 
         runOnUiThread(done); 
        } catch (InterruptedException e) { 
         // TODO Auto-generated catch block 
         e.printStackTrace(); 
        } 
     } 
    }; 

    Runnable done = new Runnable() { 
     public void run() { 
        // t.setText("done"); 
      } 
     }; 
3

per il vostro consiglio, io sto usando la maniglia e runnables per cambiare/modificare il contenuto del TextView utilizzando un "Timer". per qualche motivo, durante l'esecuzione, l'app salta sempre il secondo passaggio ("Fase due: friggere l'uovo") e mostra solo l'ultimo (terzo) passaggio ("Fase tre: servire l'uovo").

TextView t; 
private String sText; 

private Handler mHandler = new Handler(); 

private Runnable mWaitRunnable = new Runnable() { 
    public void run() { 
     t.setText(sText); 
    } 
}; 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    setContentView(R.layout.main); 

    mMonster = BitmapFactory.decodeResource(getResources(), 
      R.drawable.monster1); 

    t=new TextView(this); 
    t=(TextView)findViewById(R.id.TextView01); 

    sText = "Step One: unpack egg"; 
    t.setText(sText); 

    sText = "Step Two: fry egg";   
    mHandler.postDelayed(mWaitRunnable, 3000); 

    sText = "Step three: serve egg"; 
    mHandler.postDelayed(mWaitRunnable, 4000);  
    ... 
} 
+1

Questo non può funzionare! C'è un solo gestore - come vuoi che il tuo unico mWaitRunnable runner esistente sappia che sText è stato impostato su "Step Two" e poi su "Step 3" !! ?? Nel momento in cui viene chiamata la prima volta (dopo 3 secondi) - il valore di sText è semplicemente "Fase tre"! È necessario acquisire familiarità con le competenze di base di Java prima di provare la programmazione Android! :-) – Zordid

+0

in realtà quello che finalmente ho fatto è stato aggiunto un contatore all'interno del runnable, se è 1, il testo sarà questo, se è 2, il testo sarà questo, ecc. – user270811

145

Il tuo metodo onCreate() ha diversi difetti enormi:

1) onCreateprepara vostra attività - quindi nulla che si fa qui sarà resa visibile per l'utente fino a quando questo metodo finiture! Ad esempio, non sarà mai possibile modificare un testo di TextView qui oltre allo UNO, poiché verrà disegnata solo l'ultima modifica e quindi visibile all'utente.

2) Tenere presente che un programma Android verrà eseguito automaticamente per impostazione predefinita nel thread ONE! Quindi: non utilizzare mai Thread.sleep() o Thread.wait() nella discussione principale che è responsabile per l'interfaccia utente! (leggi "Keep your App Responsive" per ulteriori informazioni!)

Che cosa il vostro di inizializzazione della vostra attività fa è:

  • per nessun motivo si crea un nuovo oggetto TextViewt!
  • scegli il TextView del tuo layout nella variabile t in seguito.
  • si imposta il testo del t (ma tenere a mente: sarà visualizzato solo dopoonCreate() finiture e il ciclo degli eventi principale della vostra applicazione viene eseguita!)
  • di attendere 10 secondi all'interno del vostro metodo di onCreate - questo non deve mai essere eseguito in quanto interrompe tutta l'attività dell'interfaccia utente e forzerà definitivamente un ANR (Applicazione non risponde, vedere il link sopra!)
  • quindi si imposta un altro testo - questo verrà visualizzato non appena il metodo onCreate() finiture e molti altri metodi Activity lifecycle sono stati it elaborato!

La soluzione:

  1. Set testo solo una volta in onCreate() - questo deve essere il primo testo che dovrebbe essere visibile.

  2. Creare un Runnable e un Handler

    private final Runnable mUpdateUITimerTask = new Runnable() { 
        public void run() { 
         // do whatever you want to change here, like: 
         t.setText("Second text to display!"); 
        } 
    }; 
    private final Handler mHandler = new Handler(); 
    
  3. installare questo eseguibile come un gestore, possibile in onCreate() (ma leggere il mio consiglio di seguito):

    // run the mUpdateUITimerTask's run() method in 10 seconds from now 
    mHandler.postDelayed(mUpdateUITimerTask, 10 * 1000); 
    

Consigli: essere sicuro di conoscere il ciclo di vita di Activity! Se fai cose del genere in onCreate(), ciò avverrà solo quando il tuo Activity viene creato il primo tempo ! Android manterrà il tuo Activity attivo per un periodo di tempo più lungo, anche se non è visibile! Quando un utente "lo avvia" di nuovo - ed è ancora esistente - non vedrai più il tuo primo testo!


=> Installare sempre i gestori in onResume() e disabilitare in onPause()! Altrimenti riceverai "aggiornamenti" quando il tuo Activity non è affatto visibile! Nel tuo caso, se vuoi vedere di nuovo il tuo primo testo quando è riattivato, devi impostarlo su onResume(), non su onCreate()!

6

@ user264892

ho scoperto che quando si utilizza una variabile String avevo bisogno di uno prefisso con una stringa di "" o esplicitamente cast CharSequence.

Così, invece di:

String Status = "Asking Server..."; 
txtStatus.setText(Status); 

prova:

String Status = "Asking Server..."; 
txtStatus.setText((CharSequence) Status); 

o:

String Status = "Asking Server...";  
txtStatus.setText("" + Status); 

o, dal momento che la stringa non è dinamica, ancora meglio:

txtStatus.setText("AskingServer..."); 
0

:) Stai utilizzando la discussione in modo errato. Basta effettuare le seguenti operazioni:

private void runthread() 
{ 

splashTread = new Thread() { 
      @Override 
      public void run() { 
       try { 
        synchronized(this){ 

         //wait 5 sec 
         wait(_splashTime); 
        } 

       } catch(InterruptedException e) {} 
       finally { 
        //call the handler to set the text 
       } 
      } 
     }; 

     splashTread.start(); 
} 

Questo è tutto.

0

l'impostazione del testo su sam textview sovrascrive il primo testo scritto. Così la seconda volta quando usiamo setText ci basta aggiungere la nuova stringa come

textview.append("Step Two: fry egg"); 
0

@Zordid @Iambda risposta è grande, ma ho scoperto che se metto

mHandler.postDelayed(mUpdateUITimerTask, 10 * 1000); 

nel run() metodo e

mHandler.postDelayed(mUpdateUITimerTask, 0); 

nel metodo onCreate rendono l'aggiornamento continuo.