как изменить текст в Android TextView - PullRequest
91 голосов
/ 20 февраля 2010

Я пытался сделать это

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

но по какой-то причине, когда я его запускаю, появляется только второй текст. Я думаю, что это может быть связано с блокировкой метода Thread.sleep(). Так может кто-нибудь показать мне, как реализовать таймер "асинхронно"?

Спасибо.

Ответы [ 8 ]

147 голосов
/ 24 февраля 2010

Ваш onCreate() метод имеет несколько огромных недостатков:

1) onCreate готовит вашу активность - так что ничего, что вы здесь делаете, не будет сделано видимым для пользователя, пока этот метод не завершится! Например, вы никогда не сможете изменить текст TextView здесь больше, чем ONE время, так как только последнее изменение будет нарисовано и, таким образом, видимым для пользователя!

2) Имейте в виду, что программа Android по умолчанию будет работать только в потоке ONE ! Таким образом: никогда не используйте Thread.sleep() или Thread.wait() в вашем основном потоке, который отвечает за ваш пользовательский интерфейс! (читайте «Поддерживайте отзывчивость вашего приложения» для получения дополнительной информации!)

Что делает ваша инициализация вашей Деятельности:

  • без причины вы создаете новый TextView объект t!
  • вы выбираете TextView вашего макета в переменной t позже.
  • Вы устанавливаете текст t (но имейте в виду: он будет отображаться только после того, как onCreate() завершится и цикл основного события вашего приложения будет запущен!)
  • вы ждете 10 секунд в рамках вашего onCreate метода - это никогда не должно выполняться , так как оно останавливает все действия пользовательского интерфейса и обязательно вызовет ANR (приложение не отвечает, см. ссылка выше!)
  • затем вы устанавливаете другой текст - этот будет отображаться, как только ваш метод onCreate() завершится, и будет обработано несколько других жизненных циклов действий методов!

Решение:

  1. Установить текст только один раз в onCreate() - это должен быть первый текст, который должен быть виден.

  2. Создание Runnable и 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. установить этот runnable как обработчик, возможно в onCreate() (но прочтите мой совет ниже):

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

Совет: убедитесь, что вы знаете жизненный цикл Activity! Если вы делаете подобные вещи в onCreate(), это произойдет только тогда, когда ваш Activity будет создан первый раз! Android может поддерживать ваш Activity в течение более длительного периода времени, даже если он не виден! Когда пользователь «запускает» его снова - и он все еще существует - вы больше не увидите свой первый текст!


=> Всегда устанавливайте обработчики в onResume() и отключайте их в onPause()! В противном случае вы получите «обновления», когда ваш Activity вообще не виден! В вашем случае, если вы хотите увидеть свой первый текст снова при повторной активации, вы должны установить его в onResume(), а не onCreate()!

45 голосов
/ 20 февраля 2010

Я только что опубликовал этот ответ в группе Android-обсуждения Google

Если вы просто пытаетесь добавить текст в представление так, чтобы оно отображало «Шаг первый: взорвать яйцо Шаг второй: поджарить яйцо» Затем рассмотрите возможность использования t.appendText("Step Two: fry egg"); вместо t.setText("Step Two: fry egg");

Если вы хотите полностью изменить то, что находится в TextView, чтобы при запуске было написано «Шаг первый: взорвать яйцо», а затем - «Шаг второй: жарить яйцо», вы всегда можете использовать

Работоспособный пример sadboy дал

Удачи

14 голосов
/ 20 февраля 2010

В первой строке нового текстового представления нет необходимости

t=new TextView(this); 

Вы можете просто сделать это

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

что касается фонового потока, который здесь спит, является примером, но я думаю, что есть таймер, который был бы лучше для этого. вот ссылка на хороший пример использования таймера вместо http://android -developers.blogspot.com / 2007/11 / стежок-в-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 голосов
/ 20 августа 2011

@ user264892

Я обнаружил, что при использовании строковой переменной мне нужно либо поставить префикс со строкой «», либо явно привести к CharSequence.

Так что вместо:

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

попробовать:

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

или

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

или, поскольку ваша строка не является динамической, еще лучше:

txtStatus.setText("AskingServer...");
3 голосов
/ 23 февраля 2010

за ваш совет, я использую handle и runnables для переключения / изменения содержимого TextView с помощью «таймера». по какой-то причине при запуске приложение всегда пропускает второй шаг («Шаг второй: жарить яйцо») и отображает только последний (третий) шаг («Шаг третий: подать яйцо»).

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);      
    ...
}
0 голосов
/ 14 апреля 2015

@ Zordid @Iambda ответ отличный, но я обнаружил, что если поставить

mHandler.postDelayed(mUpdateUITimerTask, 10 * 1000);

в методе run () и

mHandler.postDelayed(mUpdateUITimerTask, 0);

в методе onCreate заставьте вещь обновляться.

0 голосов
/ 05 мая 2014

установка текста в sam textview дважды перезаписывает первый написанный текст. Таким образом, во второй раз, когда мы используем settext, мы просто добавляем новую строку как

textview.append("Step Two: fry egg");
0 голосов
/ 03 октября 2012

:) Вы используете ветку неправильно. Просто сделайте следующее:

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

Вот и все.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...