Я сталкиваюсь с проблемой, которая меня задевает, и я надеялся, что кто-то может дать мне несколько указателей.
Я работаю над приложением, которое использует настраиваемую ViewGroup (фактически FrameLayout, содержащую RelativeLayout) для отображения календаря событий. События внутри календаря представляются в виде представлений, размер которых зависит от продолжительности события и размера содержащего представления.
Я столкнулся с проблемой, которая возникает, когда размер FrameLayout изменяется. Текущая реализация удаляет все представления, которые представляют события, и пытается добавить новые, и рассчитать их размеры в зависимости от текущего размера FrameLayout. Эта работа запускается с помощью метода onSizeChanged() View, который переопределяется в FrameLayout.
При изменении размера представления этот код выполняется, и представления обновляются, однако ни один из них фактически не отображается на экране... представления, содержащиеся в FrameLayout, просто не видны. Если я загружу представление в инструменте hierarchyviewer, они являются частью дерева представлений и описаны в обзоре в позициях, в которых они должны находиться, но они не отображаются. (Обратите внимание, что представления видны на начальном рендере 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
Если я могу предоставить любую дополнительную информацию, пожалуйста, дайте мне знать и заблаговременно.