Тема Android XML, наследующая от двух родительских тем?

Стили и темы Android всегда вызывают у меня головокружение. Я хотел использовать пользовательский интерфейс Holo в разных версиях Android для своего приложения. Поэтому я решил извлечь необходимые ресурсы, просмотрев источник.

Я наткнулся на следующее в android-15\data\res\values\themes.xml, и я не понимаю, что именно «наследуется» и откуда:

<style name="Theme.Holo.Light" parent="Theme.Light">
    ...
    ...
</style>

В Руководстве по Android API говорится:

Если вы хотите наследовать стили, которые определили сами, вам не нужно использовать атрибут parent. Вместо этого просто добавьте префикс имени стиля, который вы хотите унаследовать, к имени вашего нового стиля, разделив их точкой.

Но из приведенного выше кода кажется, что Theme.Holo.Light наследуется от Theme.Holo и от Theme.Light.

Как это работает или что я не так читаю?


person Gautam    schedule 27.09.2012    source источник


Ответы (1)


Меня тоже это интересовало, поэтому я написал простое тестовое приложение, чтобы попробовать. Файл ресурсов выглядит так:

<!--
    Base application theme, dependent on API level. This theme is replaced
    by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
-->
<style name="AppBaseTheme" parent="android:Theme">
    <!--
        Theme customizations available in newer API levels can go in
        res/values-vXX/styles.xml, while customizations related to
        backward-compatibility can go here.
    -->
</style>

<!-- Application theme. -->
<style name="AppTheme" parent="AppBaseTheme">
    <item name="android:windowNoTitle">true</item>
    <item name="android:windowFullscreen">true</item>
    <item name="android:windowContentOverlay">@null</item>
</style>

<style name="AppTheme.TestTheme" parent="android:Theme.Light">

</style>

Поэтому я применяю AppTheme.TestTheme к активности в файле манифеста. AppTheme делает окно полноэкранным и не имеет строки заголовка. Theme.Light делает фон окна светлым, а не темным по умолчанию. Когда указан атрибут parent="android:Theme.Light", окно становится белым, а не полноэкранным — это означает, что атрибут parent="..." имеет приоритет над префиксом имени, и иерархия выглядит как TestTheme <- Theme.Light (light) <- Theme (dark).

При удалении parent="android:Theme.Light" экран становится темным и полноэкранным, поэтому иерархия TestTheme <- AppTheme (fullscreen) <- AppBaseTheme <- Theme (dark) остается на месте.

При указании parent="..." не имеет значения, уберу я префикс или нет. Таким образом, parent="...", кажется, определенно имеет приоритет. AppTheme.TestTheme не наследуется сразу от обоих родителей.

Теперь, глядя на файл themes.xml по умолчанию, кажется, что Theme.Holo.Light наследуется от Theme.Light, а затем все элементы Holo указываются вручную в его описании. Поэтому они назвали его Theme.Holo.Light не потому, что он наследуется от Holo, а потому, что им нужно было название, описывающее его как «облегченную версию Holo». И потому что они хотели сбить с толку.

Это было протестировано на Gingerbread 2.3.3.

person Shitesh    schedule 07.12.2012
comment
Это было действительно полезно. Спасибо! - person Ungureanu Liviu; 31.05.2013
comment
Два года, но все еще выручил меня. Это действительно должно быть где-то в официальной документации по стилю. - person jenzz; 21.01.2015
comment
Интересно .. У меня это не работает: Android Studio 2.3.3 Build # AI-162.4069837, собранная 6 июня 2017 г. JRE: 1.8.0_112-release-b06 x86_64 JVM: 64-разрядная виртуальная машина OpenJDK Server от JetBrains s.r.o. - person Maciej; 12.09.2017