Что вызывает меру вида () для вызова - PullRequest
42 голосов
/ 04 августа 2011

В моем приложении у меня есть бесконечный цикл для одного из переопределений onMeasure () моего View. Отлаживая исходный код, начиная с точки останова в моем onMeasure, я могу проследить себя по всей трассе стека вплоть до меры PhoneWindow $ DecorView () (самый верхний класс в моей иерархии представлений), который вызывается ViewRoot .performTraversals (). Теперь отсюда, если я продолжу перешагивать, я в конечном итоге получу снова метод measure () $ Phoneorindow $ DecorView с помощью сообщения в классе Looper.loop (). Я предполагаю, что что-то поставило в очередь сообщение, которое нужно переизмерить, как недействительный.

У меня вопрос: что инициирует необходимость вызова меры в представлении?

Из моего понимания процесса компоновки / измерения / рисования, это произойдет, только когда метод invalidate () вызывается для определенного представления, и это будет уменьшаться и выполнять передачу макета / измерения / отрисовки для этого представления, признанного недействительным и все его дети. Я бы предположил, что каким-то образом мой самый лучший вид в моей иерархии видов становится недействительным.

Тем не менее, я явно поставил точку останова на каждом отдельном вызове аннулирования, который у меня есть, и не вызываю инвалидацию каким-либо бесконечным образом. Поэтому я не думаю, что это так. Есть ли другой способ инициировать проход измерения? Может ли что-то внутренне вызвать это? Я как бы вне идей, когда вижу, что ничто не лишает силы бесконечность.

Ответы [ 2 ]

80 голосов
/ 15 декабря 2012

Чтобы инициировать проход меры для пользовательского просмотра, необходимо вызвать метод requestLayout ().Например, если вы реализуете пользовательское представление, которое расширяет View, и оно будет вести себя как TextView, вы можете написать метод setText следующим образом:

/**
 * Sets the string value of the view.
 * @param text the string to write
 */
public void setText(String text) {
    this.text = text;

            //calculates the new text width
    textWidth = mTextPaint.measureText(text);

    //force re-calculating the layout dimension and the redraw of the view
    requestLayout();
    invalidate();
}
1 голос
/ 04 августа 2011

Что ж, если вы изменяете содержимое представления, ему в конечном итоге придется вызывать invalidate (). Например, у вас есть TextView с текстом «Текст 1». Теперь вы измените текст того же TextView на «Текст 2». Здесь также будет объявлено недействительным.

Таким образом, в принципе, когда что-то меняется в представлении, чаще всего вы ожидаете вызова метода invalidate и соответствующего вызова метода measure ().

Посмотрите на исходный код для TextView, например. http://www.google.com/codesearch#uX1GffpyOZk/core/java/android/widget/TextView.java&q=TextView%20package:android&type=cs

Подсчитать количество недействительных звонков. Их немало.

...