контракт, когда вы переопределяете onMeasure (), заключается в том, что вы должны вызывать setMeasuredDimension () (и вы можете добиться этого, вызывая сам метод или вызывая super.onMeasure ())

лкнулся с проблемой, которая поставила меня в тупик, и я надеялся, что кто-то может дать мне несколько советов.

Я работаю над приложением, которое использует пользовательскую ViewGroup (фактически FrameLayout, которая содержит RelativeLayout) для визуализации календаря событий. События в календаре представлены в виде представлений, размер которых зависит от продолжительности события и размера содержащего представления.

Я сталкиваюсь с проблемой, которая возникает при изменении размера содержащего FrameLayout. Текущая реализация удаляет все представления, которые представляют события, и пытается добавить новые и рассчитать их размеры на основе текущего размера FrameLayout. Эта работа запускается с помощью метода OnSizeChanged () View, который переопределяется в FrameLayout.

Когда размер представления изменяется, этот код выполняется, и представления обновляются, однако ни одно из них фактически не отображается на экране ... представления, содержащиеся в FrameLayout, просто не видны. Если я загружаю представление в инструмент просмотра иерархии, они являются частью дерева представлений и отображаются в обзоре в тех позициях, в которых они должны быть, но они не отображаются. (Обратите внимание, что виды видны на начальном рендере FrameLayout ... только после изменения размера они исчезают.)

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

onMeasure()
onMeasure()
onSizeChanged()
onLayout()

Вызов requestLayout () после сброса представлений (внутри onSizeChanged ()), похоже, не имеет никакого эффекта. Однако, если я вызываю некоторую задержку перед вызовом requestLayout (), представления становятся видимыми. Я могу вызвать эту задержку, порождая поток и спя, или создавая фиктивную кнопку, которая просто вызывает requestLayout () и нажимает ее после изменения размера самостоятельно, или даже этот уродливый хак, помещенный в конец onSizeChanged ():

post(new Runnable() {
    public void run() {
        requestLayout();
    }
});

Когда я использую этот хак, содержащиеся представления видны, и порядок событий следующий:

onMeasure()
onMeasure()
onSizeChanged()
onLayout()
onMeasure()
onMeasure()
onLayout()

Таким образом, кажется, что принудительное выполнение второго прохода меры (после изменения дерева представлений) делает содержащиеся представления видимыми, какими они и должны быть. Почему задержка вызова метода requestLayout () делает для меня загадкой.

Кто-нибудь может дать какие-нибудь указания относительно того, что я делаю неправильно?

Я понимаю, что это несколько трудно выполнить, не глядя на некоторый код, поэтому я создал небольшой пример приложения, который демонстрирует мою проблему и сделал его доступным на Github:

https://github.com/MichaelSims/ViewGroupResizeTest

Взлом, о котором я упоминал выше, относится к отдельной ветке:

https://github.com/MichaelSims/ViewGroupResizeTest/tree/post-runnable-hack

Если я могу предоставить любую дополнительную информацию, пожалуйста, дайте мне знать и спасибо заранее.

Ответы на вопрос(2)

Ваш ответ на вопрос