So ändern Sie Text in Android TextView

91

Ich habe versucht, das zu tun

@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");

aber aus irgendeinem Grund wird nur der zweite Text angezeigt, wenn ich ihn ausführe. Ich denke, es könnte etwas mit der Thread.sleep()Methodenblockierung zu tun haben . Kann mir jemand zeigen, wie man einen Timer "asynchron" implementiert?

Vielen Dank.

user270811
quelle
2
Der Grund, warum nur die zweite Zeile .setText()angezeigt wird, ist, dass das gesamte "Widget" durch den Text ersetzt wird, den Sie festlegen sollen. EINSCHLIESSLICH Text, den Sie bereits dort abgelegt haben.
Georgiaboy82

Antworten:

45

Ich habe diese Antwort gerade in der Google-Gruppe für Android-Diskussionen gepostet

Wenn Sie nur versuchen, der Ansicht Text hinzuzufügen, sodass "Schritt Eins: Ei sprengen, Schritt Zwei: Ei braten" angezeigt wird, sollten Sie t.appendText("Step Two: fry egg"); stattdessen anstelle von verwendent.setText("Step Two: fry egg");

Wenn Sie den Inhalt vollständig ändern möchten, TextViewsodass beim Start "Schritt Eins: Ei sprengen" und später "Schritt Zwei: Ei braten" angezeigt wird, können Sie immer a verwenden

Lauffähiges Beispiel gab Sadboy

Viel Glück

snctln
quelle
147

Ihre onCreate()Methode weist mehrere große Mängel auf:

1) onCreate bereitet Ihre Aktivität vor - so wird nichts, was Sie hier tun, für den Benutzer sichtbar gemacht , bis diese Methode abgeschlossen ist! Zum Beispiel - Sie können den TextViewText eines Menschen hier nie mehr als EINMAL ändern, da nur die letzte Änderung gezeichnet und somit für den Benutzer sichtbar ist!

2) Beachten Sie, dass ein Android-Programm standardmäßig nur in EINEM Thread ausgeführt wird! Also: Verwenden Sie niemals Thread.sleep()oder Thread.wait()in Ihrem Haupt-Thread, der für Ihre Benutzeroberfläche verantwortlich ist! ( Weitere Informationen finden Sie unter "Halten Sie Ihre App ansprechbar" !)

Ihre Initialisierung Ihrer Aktivität bewirkt Folgendes:

  • ohne grund erstellen sie ein neues TextViewobjekt t!
  • Sie wählen Ihre Layouts später TextViewin der Variablen aus t.
  • Sie legen den Text von fest t(aber denken Sie daran: Er wird erst nach onCreate() Abschluss angezeigt und die Hauptereignisschleife Ihrer Anwendung wird ausgeführt!)
  • Sie warten innerhalb Ihrer Methode 10 SekundenonCreate - dies darf niemals durchgeführt werden, da dadurch alle UI-Aktivitäten gestoppt werden und definitiv eine ANR erzwungen wird (Anwendung reagiert nicht, siehe Link oben!).
  • Dann legen Sie einen anderen Text fest - dieser wird angezeigt, sobald Ihre onCreate()Methode abgeschlossen ist und mehrere andere Methoden des Aktivitätslebenszyklus verarbeitet wurden!

Die Lösung:

  1. Stellen Sie den Text nur einmal ein onCreate()- dies muss der erste Text sein, der sichtbar sein soll.

  2. Erstellen Sie ein Runnableund einHandler

    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. Installieren Sie diese ausführbare Datei als Handler, möglich in onCreate()(aber lesen Sie meinen Rat unten):

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

Hinweis: Stellen Sie sicher, dass Sie den ActivityLebenszyklus eines Menschen kennen! Wenn Sie solche Dinge tun, onCreate()geschieht dies nur, wenn Sie Activitydas erste Mal erstellt werden! Android hält Sie möglicherweise Activitylänger am Leben, auch wenn es nicht sichtbar ist! Wenn ein Benutzer es erneut "startet" - und es noch vorhanden ist - wird Ihr erster Text nicht mehr angezeigt!


=> Handler immer einbauen onResume()und deaktivieren onPause()! Andernfalls erhalten Sie "Updates", wenn Ihre überhaupt Activitynicht sichtbar sind! Wenn Sie in Ihrem Fall Ihren ersten Text wieder sehen möchten, wenn er erneut aktiviert wird, müssen Sie ihn festlegen onResume(), nicht onCreate()!

Zordid
quelle
14

Die erste Zeile der neuen Textansicht ist nicht erforderlich

t=new TextView(this); 

Sie können dies einfach tun

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

Was einen Hintergrund-Thread betrifft, der hier schläft, ist ein Beispiel, aber ich denke, es gibt einen Timer, der dafür besser wäre. Hier ist ein Link zu einem guten Beispiel, bei dem stattdessen ein Timer verwendet wird: 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");
            }
        };
Patrick Kafka
quelle
6

@ user264892

Ich fand heraus, dass ich bei Verwendung einer String-Variablen entweder einen String mit dem Präfix "" voranstellen oder explizit in CharSequence umwandeln musste.

Also statt:

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

Versuchen:

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

oder:

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

oder, da Ihre Zeichenfolge nicht dynamisch ist, noch besser:

txtStatus.setText("AskingServer...");
jwalton85
quelle
3

Gemäß Ihrem Rat verwende ich Handle und Runnables, um den Inhalt der Textansicht mithilfe eines "Timers" zu ändern. Aus irgendeinem Grund überspringt die App beim Ausführen immer den zweiten Schritt ("Schritt zwei: Ei braten") und zeigt nur den letzten (dritten) Schritt an ("Schritt drei: Ei servieren").

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);      
    ...
}
user270811
quelle
1
Das kann nicht funktionieren! Es gibt nur EINEN Handler - wie soll Ihr einziger vorhandener mWaitRunnable-Läufer "wissen", dass sText einmal auf "Schritt Zwei" und dann auf "Schritt Drei" gesetzt wurde !! ?? Zum Zeitpunkt des ersten Aufrufs (nach 3 Sekunden) ist der Wert von sText einfach "Schritt drei"! Sie sollten sich mit den grundlegenden Java-Kenntnissen vertraut machen, bevor Sie die Android-Programmierung ausprobieren! :-)
Zordid
Eigentlich habe ich endlich einen Zähler in der
ausführbaren Datei
0

:) Du benutzt den Thread falsch. Gehen Sie einfach wie folgt vor:

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

Das ist es.

Jitain Sharma
quelle
0

Wenn Sie den Text zweimal auf sam textview setzen, wird der erste geschriebene Text überschrieben. Wenn wir also zum zweiten Mal settext verwenden, hängen wir einfach die neue Zeichenfolge wie an

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

@ Zordid @ Iambda Antwort ist großartig, aber ich fand das, wenn ich sagte

mHandler.postDelayed(mUpdateUITimerTask, 10 * 1000);

in der run () Methode und

mHandler.postDelayed(mUpdateUITimerTask, 0);

In der onCreate-Methode wird das Ding ständig aktualisiert.

Kevin Zhao
quelle