Разметить вид после изменения размера
Я создаю сетку, которая отображает значения, которые меняются очень часто. Из-за этого я использую TextView, который автоматически изменяет размер при изменении его содержимого ( Auto Scale TextView Text для размещения в границах). Изменение размера происходит, но представление не размещается должным образом
Дело в том, что когда я проверяю действие с HierarchyViewer, макет отображается так, как я хочу.
Я предполагаю, что HierarchyViewer вызывает requestLayout() или invalidate() для представления, но я пробовал это безуспешно. Этот код вызывается в основной деятельности без эффекта.
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
getWindow().getDecorView().requestLayout();
getWindow().getDecorView().invalidate();
}
}, 5000);
Я также пытался сделать вид недействительным после изменения размера.
TextView имеет гравитацию, установленную в центр, и если изменение размера не происходит, это выглядит хорошо.
Любая подсказка будет приветствоваться, заранее спасибо!
3 ответа
Я решил это, переопределив onLayout в одном из родительских объектов TextView и используя обработчик, созданный в конструкторе.
public class CellView extends LinearLayout{
public CellView(Context context) {
super(context);
mHandler = new Handler();
View.inflate(context, R.layout.cellview, this);
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
if(changed){
mHandler.post(new Runnable() {
@Override
public void run() {
requestLayout();
}
});
}
super.onLayout(changed, left, top, right, bottom);
}
Я пытался вызвать requestLayout внутри onLayout TextView, хотя это не сработало, я не знаю почему. Это может быть связано с тем, что значение было обновлено через Observer, но прослушиватель onTextChanged должен происходить в потоке пользовательского интерфейса. Я надеюсь, что это служит кому-то еще
Путь requestLayout()
работа заключается в том, что при вызове представления он будет планировать передачу макета для себя и всех своих дочерних элементов. Это желательно всякий раз, когда представление смещено или изменено в размере для изменения полей, отступов или содержимого.
Документация по методу getDecorView()
не очень понятно, что именно это дает вам. Тем не менее, согласно документации на сайте:
Обратите внимание, что вызов этой функции в первый раз "блокирует" различные характеристики окна, как описано в setContentView(View, android.view.ViewGroup.LayoutParams).
Это оставляет меня верить, что есть что-то особенное в том, что getDecorView()
извлекает. Что вы, вероятно, делаете, так это делаете макет представления постоянным, таким образом никогда не меняясь, когда requestLayout()
проходить.
По-видимому, это правильный способ получить представление о корне всей вашей деятельности.
Однако, из соображений эффективности, я рекомендую звонить requestLayout()
на самого низкого ребенка вы можете. Как я уже говорил ранее, он планирует передачу макета для представления, и это дети. Если вы передадите макет самого верхнего вида, вы по сути перестраиваете все, что включает в себя виды, которые остаются на месте.
Вам, вероятно, нужно запустить код таймера в потоке пользовательского интерфейса, используя runOnUiThread, как описано здесь.