Проблемы с изменением текста TextView внутри слушателя - PullRequest
0 голосов
/ 30 декабря 2018

Я пытаюсь сделать TextView похожим на таймер и управляю временем, отображаемым с помощью SeekBar.

Сначала я получаю сообщение, что TextView должно быть окончательным, но когдаЯ изменяю, что я не могу изменить TextView с setText в слушателе.

Как я могу исправить этот код?

    SeekBar seekBar = findViewById(R.id.seekBar);
    final TextView timeView = findViewById(R.id.timeView);

    seekBar.setMax(600);
    seekBar.setProgress(30);

    seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
        @Override
        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
            int minutes = progress / 60;
            int seconds = progress - (progress * 60);

            timeView.setText(Integer.toString(minutes), ":", Integer.toString(seconds));
        }

        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {

        }

        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {

        }
    });
}

Ответы [ 4 ]

0 голосов
/ 30 декабря 2018

Действительно, простое решение состоит в том, чтобы просто изменить строку кода, в которой ОП желает использовать setText() внутри метода onProgressChanged(): нет переопределения для метода setText(), который обрабатывает эти параметры.Простое решение (как указано во многих ответах):

timeView.setText(Integer.toString(minutes) + ":" + Integer.toString(seconds));



Но ... копать глубже
TL; DR

Изначально OP хотел просто использовать TextView timeView в методе onCreate(), но компилятор предупредил, что ему нужно добавить final перед TextView timeView, чтобы можно было использовать timeView внутри анонимного внутреннего класса SeekBar.OnSeekBarChangeListener().

Однако в общем случае ключевое слово final указывает, что переменная не может быть изменена после инициализации.Хотя немного запутанный в этом особом случае с использованием final позволит внести изменения в TextView с использованием setText().

Основной проблемой является область действия.SeekBar.OnSeekBarChangeListener() является анонимным внутренним классом, а onCreate() является включающим блоком.Это (в основном) означает, что внутренний класс на самом деле не принадлежит onCreate() и что timeView находится за пределами scope метода onProgressChanged().

Конечно, добавление final к переменной метода TextView timeView "исправит" проблему - в этом особом случае (и в некоторых подобных), но не во всех случаях ;поэтому я считаю, что использование final нелогично.

Рассмотрим переменную int count = 0 или String showTime = "Show time"; изнутри onCreate(), но вне анонимного внутреннего класса.Компилятор снова выдаст предупреждение о том, что переменные должны быть объявлены final, если они должны использоваться внутри анонимного внутреннего класса.Но при этом они больше не могут быть изменены.На самом деле, код даже не скомпилируется, если попытаться изменить значения.Сделав TextView timeView; переменную класса (т. Е. Переместив ее за пределы метода onCreate()), область действия этого поля увеличится и будет включать анонимный внутренний класс.То же самое верно для переменной int count = 0 или String showTime = "Show time"; - если сделать их переменной класса, это также увеличит их область действия, включив анонимный внутренний класс, чтобы их можно было использовать и изменять внутри метода onProgressChanged().Поэтому, по моему мнению, использование переменных класса вместо final более интуитивно понятно.

Проверьте документы Java:
Анонимные классы
Доступ к членам включающего класса

0 голосов
/ 30 декабря 2018

Единственная проблема с вашим кодом - это синтаксис метода setText().setText() принимает один String (CharSequence) в качестве аргумента, поэтому измените это:

timeView.setText(Integer.toString(minutes), ":", Integer.toString(seconds));

на следующее:

timeView.setText(Integer.toString(minutes) + ":" + Integer.toString(seconds));
0 голосов
/ 30 декабря 2018

заменить

timeView.setText(Integer.toString(minutes), ":", Integer.toString(seconds));

на

timeView.setText(Integer.toString(minutes)+ ":"+ Integer.toString(seconds));
0 голосов
/ 30 декабря 2018

Попробуйте создать public Textview.Так что замените эту строку

final TextView timeView = findViewById(R.id.timeView); 

на

timeView = findViewById(R.id.timeView); 

и добавьте

TextView timeView;

по вашему OnCreate методу.

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