Я создал пользовательский компонент на основе LinearLayout. Идея состоит в том, чтобы сделать его частью XML-макета, например:
<com.test.MyComponent
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical|center_horizontal"
/>
Во время выполнения компонент динамически создает свой контент (путем добавления экземпляров подкласса View). Это отлично работает на Android 2.2 и 2.3, но на более ранних платформах компонент просто не отображается. Я потратил много времени, чтобы понять, почему он исчезает и, наконец, смог выяснить причину.
На платформах pre-2.2 Android делает "умную" оптимизацию. Он выясняет, что пользовательский класс, используемый в макете XML, представляет собой LinearLayout, и у него нет детей, поэтому он вообще не хочет отображать его.
Я пробовал многочисленные обходные пути. Единственный, который был более или менее успешным, добавляет к компоненту фиктивный вид, так что он не был пустым:
<com.test.MyComponent
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical|center_horizontal"
>
<View
android:layout_width="1px"
android:layout_height="1px"
/>
</com.test.MyComponent>
И затем добавив в код компонента следующее переопределение:
protected void dispatchDraw (Canvas canvas) {
super.dispatchDraw(canvas);
for (ChildView c : children) {
c.draw(canvas);
}
}
Это позволило отобразить компонент и его содержимое, но наличие фиктивного представления испортило взаимодействие с компонентом, и любая попытка скрыть манекен заставляет компонент исчезать.
Похоже, кто-то приложил немало усилий для создания оптимизации, которая теперь заставляет меня потратить весь день, чтобы избавиться от него. Кто-нибудь знает, есть ли способ отключить эту "полезную" оптимизацию?
Нет такой оптимизации. Вид не нарисован, если он имеет размер 0, не пересекается с отсекающим прямоугольником или полностью покрыт непрозрачным видом. Кстати, макет не будет вызывать метод onDraw(), если вы не вызываете setWillNotDraw (false) раньше.
Ваша проблема больше похожа на проблему с макетом. Вы реализовали onMeasure()? Показывая, что соответствующие части вашей реализации помогут.