Как обновить текст в динамически созданном Android TextView?

Я новичок в разработке Android, и мне нужно было быстро разработать простое приложение. Мне нужно динамически генерировать список views и использовать таймер в каждом из них, поэтому мой текущий код выглядит так:

public class MainActivity extends AppCompatActivity {
    private List<TextView> times = new ArrayList<>();
    private Handler handler;

    private void initWatchlist() {
        LinearLayout line = new LinearLayout(this);
        line.setOrientation(LinearLayout.HORIZONTAL);

        TextView time = new TextView(this);
        time.setText(sdf.format(new Date()));
        time.setTextSize(32);
        line.addView(time);
        times.add(time);

        //add couple of other views to line
        //...

        LinearLayout watchlist = findViewById(R.id.watchlist);
        watchlist.addView(line);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initWatchlist();

        Thread thread = new Thread(){
            private Calendar previousDate = Calendar.getInstance();
            public void run(){
                if (previousDate.get(Calendar.MINUTE) != Calendar.getInstance().get(Calendar.MINUTE)) {
                    for (TextView textView : times) {
                        textView.setText(sdf.format(new Date()));
                    }
                }
            }
        };

        handler = new Handler();
        handler.post(thread);
    }

    //other code
}

Итак, проблема в том, что мой Thread на самом деле ничего не делает. Я не вижу свое textviews время обновления. Что я делаю неправильно?

Calendar.getInstance() получает календарь по умолчанию с фактической датой на момент запроса, android.os.Handler запускает поток с разницей в несколько миллисекунд от его почтового вызова, поэтому условие if в потоке будет почти всегда оценить как ложь.

Tassadar 20.02.2019 00:07

Я изменил код, чтобы удалить любую зависимость от календаря, и это все равно не помогает.

shaurun 20.02.2019 00:33
0
2
42
2

Ответы 2

Чтобы обновить пользовательский интерфейс, вам нужно запустить свой код в основном потоке. Один из способов сделать это — создать обработчик, который использует MainLooper, как показано ниже.

Handler mainHandler = new Handler(Looper.getMainLooper());

Поскольку вы находитесь в своей деятельности, вы также можете использовать запуститьOnUIThread();

Спасибо за ответ, я пробовал, но на самом деле кажется, что мой поток вообще не работает. Я попытался добавить пару точек останова и простых операторов System.out.println(), удалил if - никаких реакций ниоткуда, и никакого результата с getMainLooper.

shaurun 20.02.2019 00:36

Убедитесь, что вы определили LayoutParams для вашего TextView (stackoverflow.com/questions/4203506/…). Когда вы отлаживаете, заполняется ли ваш ArrayList TextView? Насколько длинным может быть ваш список? Более простой способ добиться этого — добавить RecylerView(developer.android.com/guide/topics/ui/layout/rec‌​yclerview) в ваш LinearLayout в XML и определить адаптер для заполнения произвольного количества TextView. Потому что в настоящее время вы вкладываете два LinearLayouts, когда в этом нет необходимости.

Nelson Hoang 20.02.2019 00:46

Я тупой. Мой поток на самом деле был завершен довольно быстро, потому что он не содержал while(true) {} или что-то в этом роде;

Проблема была решена путем добавления дополнительного handler.postDelayed(thread, 1000) в мою функцию thread.run().

Другие вопросы по теме