як змінити текст в Android TextView - -


91

Я намагався це зробити

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

Дякую.


2
Причиною того, що він відображає лише другий рядок, є те, що .setText()замінює весь "віджет" текстом, який ви наказали йому встановити; Включаючи текст, який ви вже там помістили.
georgiaboy82

Відповіді:


45

Я щойно опублікував цю відповідь у групі Google для обговорення android-discuss

Якщо ви просто намагаєтеся додати текст до подання, щоб воно відображало "Крок перший: вибух яйцем Крок другий: смаження яйця" Тоді подумайте про використання t.appendText("Step Two: fry egg"); замістьt.setText("Step Two: fry egg");

Якщо ви хочете повністю змінити те, що в TextView так, щоб під час запуску на ньому було написано "Крок перший: вибухове яйце", а потім - "Крок другий: смажити яйце", ви завжди можете використовувати

Біговий приклад дав садбой

Удачі


146

Ваш onCreate()метод має кілька величезних недоліків:

1) onCreate готує Вашу Діяльність - тому нічого, що Ви тут робите, не стане видимим для користувача, поки цей метод не закінчиться! Наприклад - ви ніколи не зможете змінити TextViewтекст тексту тут більше, ніж ОДИН раз, оскільки лише остання зміна буде намальована і, таким чином, видима для користувача!

2) Майте на увазі, що програма Android - за замовчуванням працюватиме лише в ОДНОМУ потоці! Отже: ніколи не використовуйте Thread.sleep()або не використовуйте Thread.wait()у своєму головному потоці, який відповідає за ваш інтерфейс! (читайте "Тримайте додаток чуйним" для отримання додаткової інформації !)

Ваша ініціалізація Вашої активності:

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

Рішення:

  1. Встановіть текст лише один раз onCreate()- це повинен бути перший текст, який повинен бути видимим.

  2. Створіть a Runnableта aHandler

    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

@ користувач264892

Я виявив, що при використанні змінної 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...");

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

1
Це не може працювати! Є лише ОДИН обробник - як ви хочете, щоб ваш єдиний існуючий бігун mWaitRunnable "знав", що sText колись був встановлений на "Крок другий", а потім на "Крок третій" !! ?? До того часу, коли він називається першим разом (через 3 секунди) - значення sText просто "Крок третій"! Вам слід ознайомитися з базовими навичками роботи Java перед тим, як спробувати програмувати Android! :-)
Зордід

насправді те, що я нарешті зробив, додав лічильник всередині запущеного, якщо це 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

встановлення тексту в два рази для текстового перегляду - це перезапис першого написаного тексту. Отже, вдруге, коли ми використовуємо settext, ми просто додаємо новий рядок як

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

0

@Zordid @Iambda відповідь чудова, але я виявив, що якщо поставити

mHandler.postDelayed(mUpdateUITimerTask, 10 * 1000);

у методі run () та

mHandler.postDelayed(mUpdateUITimerTask, 0);

у методі onCreate змусити річ продовжувати оновлюватись.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.