comment changer le texte dans Android TextView

91

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 l'exécute. Je pense que cela pourrait avoir quelque chose à voir avec le Thread.sleep()blocage de méthode. Alors quelqu'un peut-il me montrer comment implémenter une minuterie de manière "asynchrone"?

Merci.

user270811
la source
2
La raison pour laquelle il n'affiche que la deuxième ligne est parce que .setText()remplace le "widget" entier par le texte que vous lui demandez de définir; Y COMPRIS le texte que vous y avez déjà mis.
georgiaboy82

Réponses:

45

Je viens de publier cette réponse dans le groupe google android-discussion

Si vous essayez simplement d'ajouter du texte à la vue afin qu'elle affiche "Étape 1: faire sauter l'œuf Étape 2: faire frire l'œuf" Alors envisagez d'utiliser t.appendText("Step Two: fry egg"); au lieu det.setText("Step Two: fry egg");

Si vous voulez changer complètement ce qui est dans le TextViewpour qu'il dise «Étape un: blast egg» au démarrage, puis il dit «Étape deux: faire frire l'œuf» à un moment plus tard, vous pouvez toujours utiliser un

Exemple exécutable donné par Sadboy

Bonne chance

snctln
la source
146

Votre onCreate()méthode présente plusieurs défauts énormes:

1) onCreate prépare votre activité - donc rien de ce que vous faites ici ne sera rendu visible à l'utilisateur tant que cette méthode ne sera pas terminée! Par exemple - vous ne serez jamais en mesure de modifier un TextViewici plus que le texte » ONE temps que seul le dernier changement sera établi et donc visible pour l'utilisateur!

2) Gardez à l'esprit qu'un programme Android ne fonctionnera - par défaut - que dans UN thread! Ainsi: n'utilisez jamais Thread.sleep()ou Thread.wait()dans votre thread principal qui est responsable de votre UI! (lisez «Gardez votre application réactive» pour plus d'informations!)

Ce que fait votre initialisation de votre activité est:

  • sans raison, vous créez un nouvel TextViewobjet t!
  • vous choisissez votre mise en page TextViewdans la variable tplus tard.
  • vous définissez le texte de t(mais gardez à l'esprit: il ne sera affiché qu'après la onCreate() fin et la boucle d'événement principal de votre application s'exécute!)
  • vous attendez 10 secondes dans votre onCreateméthode - cela ne doit jamais être fait car cela arrête toute activité de l'interface utilisateur et forcera définitivement un ANR (Application Not Responding, voir le lien ci-dessus!)
  • puis vous définissez un autre texte - celui-ci sera affiché dès que votre onCreate()méthode se terminera et que plusieurs autres méthodes de cycle de vie d'activité auront été traitées!

La solution:

  1. Ne définissez le texte qu'une seule fois onCreate()- ce doit être le premier texte à être visible.

  2. Créer un Runnableet unHandler

    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 mes conseils ci-dessous):

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

Conseil: assurez-vous de connaître Activityle cycle de vie d' un an ! Si vous faites des choses comme ça, onCreate()cela n'arrivera que lorsque votre Activitysera créé pour la première fois! Android vous gardera probablement en Activityvie plus longtemps, même s'il n'est pas visible! Lorsqu'un utilisateur le «redémarre» - et il existe toujours - vous ne verrez plus votre premier texte!


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

Zordid
la source
14

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

t=new TextView(this); 

tu peux juste faire ça

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

dans la mesure où un fil d'arrière-plan qui dort ici est un exemple, mais je pense qu'il y a une minuterie qui serait mieux pour cela. 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");
            }
        };
Patrick Kafka
la source
6

@ user264892

J'ai trouvé que lors de l'utilisation d'une variable String, j'avais besoin de préfixer avec une chaîne de "" ou de cast explicitement 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, encore mieux:

txtStatus.setText("AskingServer...");
jwalton85
la source
3

selon vos conseils, j'utilise handle et runnables pour changer / changer le contenu du TextView en utilisant un "timer". pour une raison quelconque, lors de l'exécution, l'application ignore toujours la deuxième étape ("Étape deux: faire frire l'œuf") et n'affiche que la dernière (troisième) étape ("Étape trois: servir 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);      
    ...
}
user270811
la source
1
Cela ne peut pas fonctionner! Il n'y a qu'un seul gestionnaire - comment voulez-vous que votre seul coureur mWaitRunnable existant "sache" que sText a déjà été réglé sur "Step Two" puis sur "Step three" !! ?? Au moment où il est appelé la première fois (après 3 secondes) - la valeur de sText est simplement "Étape trois"! Vous devez vous familiariser avec les compétences de base Java avant d'essayer la programmation Android! :-)
Zordid
en fait ce que j'ai finalement fait a été ajouté un compteur à l'intérieur du runnable, si c'est 1, le texte sera ceci, si c'est 2, le texte sera ceci, etc.
user270811
0

:) Vous utilisez le fil de manière incorrecte. Faites 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 tout.

jitain sharma
la source
0

définir deux fois le texte sur sam textview remplace 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");
Disha
la source
0

La réponse @Zordid @Iambda est excellente, mais j'ai trouvé que si je mets

mHandler.postDelayed(mUpdateUITimerTask, 10 * 1000);

dans la méthode run () et

mHandler.postDelayed(mUpdateUITimerTask, 0);

dans la méthode onCreate, faites en sorte que la chose se mette à jour.

Kevin Zhao
la source