web-dev-qa-db-fra.com

comment changer le texte dans Android TextView

J'ai essayé de faire ça

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

mais pour une raison quelconque, seul le deuxième texte apparaît lorsque je le lance. Je pense que cela pourrait avoir quelque chose à voir avec le blocage de la méthode Thread.sleep(). Alors, quelqu'un peut-il me montrer comment implémenter une minuterie "de manière asynchrone"?

Merci.

91
user270811

Je viens de poster cette réponse dans le groupe Google Google-discussion

Si vous essayez simplement d’ajouter du texte à la vue de sorte qu’elle affiche "Première étape: Blast Egg - Deuxième étape: Fry Egg", envisagez d’utiliser t.appendText("Step Two: fry Egg"); au lieu de t.setText("Step Two: fry Egg");.

Si vous voulez changer complètement le contenu de la TextView de sorte qu'il soit écrit "Première étape: Sabler l'oeuf" au démarrage, puis "Deuxième étape: frire l'oeuf" à la fois, vous pouvez toujours utiliser un

Exemple runnable donné par sadboy

Bonne chance

45
snctln

Votre méthode onCreate() comporte plusieurs failles importantes:

1) onCreate prépare votre activité - de sorte que rien de ce que vous faites ici ne sera rendu visible à l'utilisateur jusqu'à la fin de cette méthode! Par exemple, vous ne pourrez jamais modifier le texte d'une TextView plus de UNE fois, car seul le dernier changement sera tracé. et donc visible pour l'utilisateur!

2) N'oubliez pas qu'un programme Android _ sera - par défaut - exécuté uniquement UN! Ainsi: n'utilisez jamais Thread.sleep() ou Thread.wait() dans votre thread principal qui est responsable de votre interface utilisateur! (lisez "Gardez votre application sensible" pour plus d'informations!)

Votre initialisation de votre activité est la suivante:

  • sans aucune raison, vous créez un nouvel objet TextViewt!
  • vous choisissez votre TextView de votre mise en page dans la variable t plus tard.
  • vous définissez le texte de t (mais gardez à l'esprit: il sera affiché uniquement après onCreate() se termine et l'événement principal boucle de votre application s'exécute!)
  • vous attendez 10 secondes dans votre méthode onCreate - ceci ne doit jamais être effectué car il arrête toute activité de l'interface utilisateur et forcera un ANR (application ne répondant pas, voir le lien ci-dessus!)
  • puis vous définissez un autre texte - celui-ci sera affiché dès que votre méthode onCreate() sera terminée et plusieurs autres méthodes cycle de vie de l'activité ont été traitées!

La solution:

  1. Définissez le texte une seule fois dans onCreate() - ce doit être le premier texte visible.

  2. Créer une Runnable et une 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. installez ce runnable en tant que gestionnaire, possible dans onCreate() (mais lisez mon conseil ci-dessous):

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

Conseil: assurez-vous de connaître le cycle de vie d'un Activity! Si vous faites ce genre de choses dans onCreate() cela ne se produira que lorsque votre Activity sera créé le en premier ! Android maintiendra éventuellement votre Activity plus longtemps, même si elle n'est pas visible! Lorsqu'un utilisateur le "redémarre" - et qu'il existe toujours - vous ne verrez plus votre premier texte!


=> Toujours installer les gestionnaires dans onResume() et les désactiver dans onPause()! Sinon, vous obtiendrez des "mises à jour" lorsque votre Activity ne sera pas visible du tout! Dans votre cas, si vous souhaitez voir votre premier texte à nouveau lorsqu'il est réactivé, vous devez le définir dans onResume(), pas onCreate()!

147
Zordid

La première ligne de la nouvelle vue de texte est inutile

t=new TextView(this); 

tu peux juste faire ça

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

en ce qui concerne le fil de fond qui dort ici, c’est un exemple, mais je pense qu’il existe une minuterie qui conviendrait mieux. voici un lien vers un bon exemple utilisant une minuterie à la place 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");
            }
        };
14
Patrick Kafka

@ user264892

J'ai constaté qu'en utilisant une variable String, je devais soit préfixer d'une chaîne "", soit explicitement converti en CharSequence.

Donc au lieu de:

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

essayer:

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

ou:

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

ou, puisque votre chaîne n'est pas dynamique, c'est encore mieux:

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

selon vos conseils, j'utilise handle et runnables pour changer/changer le contenu du TextView à l'aide d'un "timer". pour une raison quelconque, lors de l'exécution, l'application saute toujours la deuxième étape ("Deuxième étape: frire des œufs") et n'affiche que la dernière (troisième) étape ("Troisième étape: servir de l'œuf").

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);      
    ...
}
3
user270811

La réponse de @Zordid @Iambda est excellente, mais j'ai constaté que si je mettais

mHandler.postDelayed(mUpdateUITimerTask, 10 * 1000);

dans la méthode run () et

mHandler.postDelayed(mUpdateUITimerTask, 0);

dans la méthode onCreate, la chose continue à se mettre à jour.

0
Kevin Zhao

régler le texte sur sam textview deux fois revient à écraser le premier texte écrit. Donc, la deuxième fois que nous utilisons settext, nous ajoutons simplement la nouvelle chaîne comme

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

:) Votre utilisation du fil de manière incorrecte. Il suffit de faire ce qui suit:

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

C'est ça.

0
jitain sharma