como alterar o texto no Android TextView

91

Eu tentei fazer isso

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

mas, por algum motivo, apenas o segundo texto aparece quando eu o executo. Acho que pode ter algo a ver com o Thread.sleep()bloqueio do método. Alguém pode me mostrar como implementar um temporizador "de forma assíncrona"?

Obrigado.

user270811
fonte
2
O motivo pelo qual ele mostra apenas a segunda linha é porque .setText()substitui todo o "widget" pelo texto que você instruiu a definir; INCLUINDO texto que você já colocou lá.
georgiaboy82

Respostas:

45

Acabei de postar esta resposta no grupo android-discuss google

Se você está apenas tentando adicionar texto à exibição para que ela exiba "Etapa um: ovo queimado Etapa dois: ovo frito" Considere usar em t.appendText("Step Two: fry egg"); vez det.setText("Step Two: fry egg");

Se você quiser mudar completamente o que está no TextViewpara que diga "Etapa um: ovo explodido" na inicialização e depois "Etapa dois: ovo frito", você sempre pode usar um

Exemplo executável de sadboy dado

Boa sorte

snctln
fonte
146

Seu onCreate()método tem várias falhas enormes:

1) onCreate prepara sua atividade - então nada do que você fizer aqui ficará visível para o usuário até que este método seja concluído! Por exemplo - você nunca poderá alterar TextViewo texto de um aqui mais de UMA vez, pois apenas a última alteração será desenhada e, portanto, visível para o usuário!

2) Tenha em mente que um programa Android irá - por padrão - rodar em apenas UM thread! Portanto: nunca use Thread.sleep()ou Thread.wait()em seu thread principal que é responsável por sua IU! (leia "Mantenha seu aplicativo responsivo" para obter mais informações!)

O que a inicialização de sua atividade faz é:

  • sem motivo, você cria um novo TextViewobjeto t!
  • você escolhe seu layout TextViewna variável tmais tarde.
  • você define o texto de t(mas lembre-se: ele será exibido apenas após o término onCreate() e o loop de evento principal do seu aplicativo for executado!)
  • você espera por 10 segundos dentro do seu onCreatemétodo - isso nunca deve ser feito , pois interrompe todas as atividades da IU e definitivamente forçará um ANR (Aplicativo não está respondendo, consulte o link acima)
  • então você define outro texto - este será exibido assim que seu onCreate()método terminar e vários outros métodos de ciclo de vida de atividade tiverem sido processados!

A solução:

  1. Defina o texto apenas uma vez onCreate()- este deve ser o primeiro texto que deve estar visível.

  2. Crie um Runnablee umHandler

    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. instale este executável como um gerenciador, possível em onCreate()(mas leia meu conselho abaixo):

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

Conselho: conheça bem Activityo ciclo de vida de! Se você fizer coisas assim, onCreate()isso só acontecerá quando o seu Activityfor criado pela primeira vez! O Android possivelmente o manterá Activityvivo por um longo período de tempo, mesmo que não esteja visível! Quando um usuário "inicia" novamente - e ele ainda existe - você não verá mais o seu primeiro texto!


=> Sempre instale manipuladores onResume()e desative-os onPause()! Caso contrário, você receberá "atualizações" quando Activitynão estiver visível de forma alguma! No seu caso, se quiser ver o primeiro texto novamente quando for reativado, você deve configurá-lo onResume(), não onCreate()!

Zordid
fonte
14

A primeira linha da nova janela de texto é desnecessária

t=new TextView(this); 

você pode apenas fazer isso

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

quanto a um thread de fundo que dorme aqui é um exemplo, mas acho que há um cronômetro que seria melhor para isso. aqui está um link para um bom exemplo usando um cronômetro em vez 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
fonte
6

@ user264892

Descobri que, ao usar uma variável String, precisava prefixar com uma String "" ou converter explicitamente em CharSequence.

Então, em vez de:

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

experimentar:

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

ou:

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

ou, já que sua string não é dinâmica, melhor ainda:

txtStatus.setText("AskingServer...");
Jwalton85
fonte
3

de acordo com seu conselho, estou usando o identificador e executáveis ​​para alternar / alterar o conteúdo do TextView usando um "cronômetro". por algum motivo, ao ser executado, o aplicativo sempre pula a segunda etapa ("Etapa dois: frite o ovo") e mostra apenas a última (terceira) etapa ("Etapa três: servir o ovo").

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
fonte
1
Isso não pode funcionar! Há apenas UM manipulador - como você deseja que seu único runner mWaitRunnable existente "saiba" que sText foi definido para "Etapa dois" e depois para "Etapa três" !! ?? No momento em que é chamado pela primeira vez (após 3 segundos) - o valor de sText é simplesmente "Etapa três"! Você deve se familiarizar com as habilidades básicas de Java antes de tentar a programação Android! :-)
Zordid
na verdade, o que eu finalmente fiz foi adicionar um contador dentro do executável, se for 1, o texto será este, se for 2, o texto será este, etc.
user270811
0

:) Você está usando o tópico de maneira errada. Basta fazer o seguinte:

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

É isso aí.

jitain sharma
fonte
0

configurar o texto para sam textview duas vezes é sobrescrever o primeiro texto escrito. Então, na segunda vez, quando usamos settext, apenas acrescentamos a nova string como

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

@Zordid @Iambda a resposta é ótima, mas descobri que se colocasse

mHandler.postDelayed(mUpdateUITimerTask, 10 * 1000);

no método run () e

mHandler.postDelayed(mUpdateUITimerTask, 0);

no método onCreate faz com que a coisa continue atualizando.

Kevin zhao
fonte