Там поставить бесконечный цикл, который умеет менять TextView? - PullRequest
0 голосов
/ 04 апреля 2019

Мой первый Android-проект, мой первый Kotlin Project (примеры Java помогли бы мне)

Проблема в следующем: у меня есть TextView.Я могу изменить текст с кодом.Но проблема в том, что, похоже, моя активность должна завершиться, чтобы могли произойти изменения в графическом интерфейсе.

myTextView.setText("x = $x") //this works once 

do{  
myTextView.setText("x = $x") //this doesnt work  
println("x = $x") //this works on standart io  
x++  
}while(true)  

do{  
myTextView.setText("x = $x") //this doesnt work until x reaches its limit   
x++  
}while(x<100)  

Что я пробовал до сих пор: Запустить другой поток с HandlerThread и попробовать его там (неработать, потому что «Только исходный поток, создавший иерархию представлений, может касаться его представлений».)

Сначала мой код был в onCreate, я понял, что перемещение его в onResume было лучшей идеей, так что, по крайней мере, он устанавливаеттекст каждый раз, когда я переключаюсь на домашний экран и возвращаюсь.Но это все еще не решение.

Единственный обходной путь, который я имею в виду, - это использовать Handler.post () в том же потоке для создания цикла, но я не уверен, что это будет работать, также это кажется неправильным способомчтобы сделать это, я бы предпочел цикл while таким же образом, как и с println () в стандарте.Может быть, есть какой-то метод обновления графического интерфейса, который мне нужно вызывать внутри цикла, но я не знаю, существует ли такая вещь.

Ответы [ 2 ]

0 голосов
/ 04 апреля 2019

Проблема: Вы хотите обновить TextView в бесконечном цикле или цикле с верхней границей.

Решение: Использование Handler.post() и Handler.postDelayed() вместе.

Случай 1: Обновление TextView в бесконечном цикле.

val uiHandler = Handler()

var x = 1
uiHandler.post(object : Runnable {
    override fun run() {
        myTextView.setText("x = $x")
        println("x = $x")
        x++
        // Delay 100 milliseconds to see the text is updated in the TextView.
        // You can set this to smaller value, such as 10 or 50, etc...
        uiHandler.postDelayed(this, 100)
    }
})

Случай 2: Обновление TextView в цикле с верхней границей.

val uiHandler = Handler()

var x = 1
uiHandler.post(object : Runnable {
    override fun run() {
        myTextView.setText("x = $x")
        println("x = $x")
        x++
        // Exit the loop when it reaches the upper bound (100 in this case).
        if (x < 100) {
            uiHandler.postDelayed(this, 100)
        }
    }
})
0 голосов
/ 04 апреля 2019

Непонятно, что вы пытаетесь сделать здесь, в своем приложении ... Если это простое TextView, которое насчитывает до 100, вам придется использовать отдельный поток для подсчета и ожидания, есливы не хотите, чтобы ваше приложение было вялым.

В android поток пользовательского интерфейса Activity по существу находится в постоянном цикле, ожидая ввода данных пользователем и изменений в представлениях, которые будут отправлены в очередь, которую он обрабатывает последовательно,По этой причине рекомендуется держать бизнес-логику вне основного потока.Любые длительные операции с ним будут задерживать выполнение задания, для которого он предназначен - вычислять виды представлений и обновлять экран 60 раз в секунду.

Один из способов сделать это - AsyncTask, средствосоздание нового потока для запуска некоторой бизнес-логики, которая предоставляет методы для обновления основного потока пользовательского интерфейса, когда это будет сделано.

Создайте внутренний класс в MainActivity, который будет выглядеть следующим образом:

private class CounterTask extends AsyncTask<Integer, Integer, Boolean> {
    @Override
    protected Boolean doInBackground(Integer... integers) {
        int count = 100;
        for (int i = 0; i < count; i++) {
            try {              
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            publishProgress(i);
        }
        return true;
    }

    @Override
    protected void onProgressUpdate(Integer... status) {
        super.onProgressUpdate(status);
        int current = status[0];
        TextView textView = findViewById(R.id.counter_text_view);
        textView.setText(String.valueOf(current));
    }
}

Затем в методе Activity onCreate создайте и выполните эту задачу следующим образом:

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

    // Run your counter task
    CounterTask task = new CounterTask();
    task.execute();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...