come cambiare il testo in Android TextView


91

Ho provato a farlo

@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, quando lo eseguo viene visualizzato solo il secondo testo. Penso che potrebbe avere qualcosa a che fare con il Thread.sleep()blocco del metodo. Quindi qualcuno può mostrarmi come implementare un timer "in modo asincrono"?

Grazie.


2
Il motivo per cui mostra solo la seconda riga è perché .setText()sostituisce l'intero "widget" con il testo che gli dici di impostare; COMPRESO il testo che hai già messo lì.
georgiaboy82

Risposte:


45

Ho appena pubblicato questa risposta nel gruppo google android-discuss

Se stai solo tentando di aggiungere del testo alla vista in modo che venga visualizzato "Passaggio uno: scoppiare l'uovo Passaggio due: soffriggere l'uovo", allora considera l'utilizzo t.appendText("Step Two: fry egg"); invece dit.setText("Step Two: fry egg");

Se vuoi cambiare completamente ciò che è nel file TextView modo che sia visualizzato "Step One: blast egg" all'avvio e poi "Step Two: fry egg" in un momento successivo, puoi sempre usare un

Esempio eseguibile che ha dato sadboy

In bocca al lupo


146

Il tuo onCreate()metodo ha diversi enormi difetti:

1) onCreate prepara la tua attività, quindi nulla di ciò che fai qui sarà reso visibile all'utente fino al termine di questo metodo! Ad esempio, non sarai mai in grado di modificare TextViewil testo di un qui più di UNA volta poiché solo l'ultima modifica verrà disegnata e quindi visibile all'utente!

2) Tieni presente che un programma Android, per impostazione predefinita, verrà eseguito in UN solo thread! Quindi: non usare mai Thread.sleep()o Thread.wait()nel thread principale che è responsabile della tua interfaccia utente! (leggi "Mantieni la tua app reattiva" per ulteriori informazioni!)

Ciò che fa l' inizializzazione della tua attività è:

  • per nessun motivo crei un nuovo TextViewoggetto t!
  • scegli il tuo layout TextViewnella variabile in tseguito.
  • hai impostato il testo di t(ma tieni presente: verrà visualizzato solo al onCreate() termine e verrà eseguito il ciclo di eventi principale della tua applicazione!)
  • attendi 10 secondi all'interno del tuo onCreatemetodo - questo non deve mai essere fatto poiché interrompe tutte le attività dell'interfaccia utente e forzerà sicuramente un ANR (Applicazione non risponde, vedi link sopra!)
  • quindi imposti un altro testo: questo verrà visualizzato non appena il tuo onCreate()metodo termina e diversi altri metodi del ciclo di vita dell'attività sono stati elaborati!

La soluzione:

  1. Imposta il testo solo una volta dentro onCreate(): deve essere il primo testo che dovrebbe essere visibile.

  2. Crea un Runnablee un fileHandler

    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. installa questo eseguibile come gestore, possibile in onCreate()(ma leggi il mio consiglio di seguito):

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

Consiglio: assicurati di conoscere Activityil ciclo di vita di! Se fai cose del genere in onCreate()questo accadrà solo quando il tuo Activityviene creato la prima volta! Android probabilmente ti manterrà in Activityvita 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!


=> Installa sempre gli handler onResume()e disabilitali onPause()! Altrimenti riceverai "aggiornamenti" quando il tuo Activitynon è affatto visibile! Nel tuo caso, se vuoi vedere di nuovo il tuo primo testo quando viene riattivato, devi impostarlo onResume(), no onCreate()!


14

La prima riga della nuova visualizzazione del testo non è necessaria

t=new TextView(this); 

puoi semplicemente farlo

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

per quanto riguarda un thread in background che dorme qui è un esempio, ma penso che ci sia un timer che sarebbe meglio per questo. ecco un collegamento a un buon esempio che utilizza 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");
            }
        };

6

@ user264892

Ho scoperto che quando si utilizza una variabile String, è necessario aggiungere un prefisso a una stringa "" o eseguire il cast esplicito a CharSequence.

Quindi invece di:

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

provare:

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

o:

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

oppure, poiché la tua stringa non è dinamica, ancora meglio:

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

3

secondo il tuo consiglio, sto usando handle e runnables per cambiare / modificare il contenuto di TextView usando un "timer". per qualche motivo, durante l'esecuzione, l'app salta sempre il secondo passaggio ("Passaggio due: friggere l'uovo") e mostra solo l'ultimo (terzo) passaggio ("Passaggio 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'è solo UN gestore: come vuoi che il tuo unico runner mWaitRunnable esistente "sappia" che sText una volta era impostato su "Step Two" e poi su "Step tre" !! ?? Quando viene chiamato la prima volta (dopo 3 secondi) - il valore di sText è semplicemente "Step three"! Dovresti familiarizzare con le competenze di base di Java prima di provare la programmazione Android! :-)
Zordid

in realtà quello che ho fatto alla fine è stato aggiungere un contatore all'interno del eseguibile, se è 1, il testo sarà questo, se è 2, il testo sarà questo, ecc.
user270811

0

:) Stai usando il thread in modo sbagliato. Basta fare quanto segue:

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

impostare il testo su sam textview due volte significa sovrascrivere il primo testo scritto. Quindi la seconda volta che usiamo settext aggiungiamo semplicemente la nuova stringa come

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

0

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

mHandler.postDelayed(mUpdateUITimerTask, 10 * 1000);

nel metodo run () e

mHandler.postDelayed(mUpdateUITimerTask, 0);

nel metodo onCreate fai in modo che la cosa continui ad aggiornarsi.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.