#android #layout
#Android #макет
Вопрос:
Я создаю макет программно и мне нужно добавить TextView. Единственная проблема в том, что мне нужно сделать TextView глобальной переменной, чтобы к ней можно было обращаться с помощью разных методов (нужно вызвать метод setText () в другом месте).
ScrollView scroll = new ScrollView(this);
LinearLayout linear = new LinearLayout(this);
linear.setOrientation(LinearLayout.VERTICAL);
scroll.addView(linear);
TextView time = new TextView(this);
time.setText("Some text");
linear.addView(time);
new CountDownTimer(30000, 1000) {
public void onTick(long millisUntilFinished) {
time.setText("seconds remaining: " millisUntilFinished / 1000);
} // 'time' not accessible
public void onFinish() {
time.setText("done!");
}
}.start(); */
this.setContentView(scroll);
Итак, моя проблема в том, что я создаю текстовое представление ‘time’, но метод CountDownTimer не может получить к нему доступ. Я пытаюсь использовать TextView time = new TextView(this);
в верхней части моего кода с конструкторами, чтобы он был глобальным, но это вызывает исключение — «невозможно создать activity ComponentInfo» и «исключение нулевой точки». Исключение не указывает, какая строка конкретно вызывает проблему, но это TextView timeLeft = new TextView(this);
точно!
Комментарии:
1. Почему вы не используете файл XML layout для определения вашего представления? Просто любопытно.
2. Кроме того, где в вашем коде вы вызываете setContentView?
3. Это только часть кода (та часть, с которой у меня возникли проблемы). Причина, по которой я создаю макет программно, поскольку ранее к нему добавлено неопределенное количество кнопок. setContentView находится (как указано выше) в нижней части кода после каждой кнопки, а
time
TextView добавляется к макету.4. Ах, извините. Я сосредоточился на верхней части кода и не увидел setContentView (). Ого!
Ответ №1:
Я бы создал переменную-член в вашем Activity ( mTime
). Тогда CountDownTimer сможет получить доступ к переменной-члену в любое время.
В качестве альтернативы вы можете объявить time
final:
final TextView time = new TextView(this);
Комментарии:
1. Теперь это работает, объявив
time
какfinal
, это нормально для этого?time
изменяется каждый раз, когда таймер останавливается, поскольку это таймер обратного отсчета. Я немного смущен тем, что делают конечные переменные, поскольку, похоже, это довольно удачно модифицирует его. Я полагаю, лучше залезть в Википедию и прочитать!
Ответ №2:
Вы могли бы назначить id
(скажем: myTextViewId
) своему TextView
перед добавлением его в представление, а позже вы можете просто ссылаться на это TextView с помощью findViewById(myTextViewId);
.
Та же ситуация, если вы расширяете свой TextView, используя XML-файл, и назначаете идентификатор внутри него. Затем вы можете обратиться к этому TextView с помощью findViewById(R.id.myTextView);
.
Или, наконец, поскольку вы не можете создать этот TextView одновременно final
(он не будет инициализирован сразу или в конструкторе) и class-level
(private, protected и т.д.), Я бы посоветовал сделать его частной переменной внутри вашего класса.
Чтобы получить к нему доступ, ваш метод должен выполняться в потоке пользовательского интерфейса, но у таймера есть свой собственный поток, поэтому вы должны использовать Handler
, а из вашего TimreTask
метода run просто отправьте ему пустое сообщение.
В вашем Handler
handleMessage(Message msg)
методе вы можете безопасно получить доступ к своему TextView
, либо он является членом вашего класса, либо просто зная его id
.