как изменить текст в Android TextView

92

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

@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()блокировкой метода. Так может ли кто-нибудь показать мне, как реализовать таймер «асинхронно»?

Спасибо.

user270811
источник
2
Причина, по которой он показывает только вторую строку, состоит в том, что .setText()заменяет весь «виджет» текстом, который вы ему указываете ; ВКЛЮЧАЯ текст, который вы там уже поместили.
georgiaboy82 01

Ответы:

46

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

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

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

Сэдбой дал беглый пример

Удачи

snctln
источник
146

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

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

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

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

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

Решение:

  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. установить этот исполняемый файл в качестве обработчика, возможно 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()!

Зордид
источник
14

Первая строка нового текстового представления не нужна

t=new TextView(this); 

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

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

Что касается спящего фонового потока, то вот пример, но я думаю, что для этого лучше подойдет таймер. вот ссылка на хороший пример с использованием таймера вместо 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");
            }
        };
Патрик Кафка
источник
6

@ user264892

Я обнаружил, что при использовании строковой переменной мне нужно либо использовать префикс String со значением «», либо явно привести к 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...");
jwalton85
источник
3

по вашему совету я использую дескриптор и 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);      
    ...
}
user270811
источник
1
Это не может работать! Есть только ОДИН обработчик - как вы хотите, чтобы ваш единственный существующий бегун mWaitRunnable "знал", что sText когда-то был установлен на "Шаг два", а затем на "Шаг третий" !! ?? К моменту его первого вызова (через 3 секунды) значение sText просто равно «Шаг третий»! Вы должны ознакомиться с базовыми навыками Java, прежде чем пробовать программировать на Android! :-)
Zordid
на самом деле я, наконец, добавил счетчик внутри runnable, если он 1, текст будет таким, если 2, текст будет таким и т.д.
user270811
0

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

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

Вот и все.

Джитайн Шарма
источник
0

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

textview.append("Step Two: fry egg");
Диша
источник
0

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

mHandler.postDelayed(mUpdateUITimerTask, 10 * 1000);

в методе run () и

mHandler.postDelayed(mUpdateUITimerTask, 0);

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

Кевин Чжао
источник