経緯
AppCompatActivityを使って、AppCompatテーマを適応することで、色などに統一感を持たせることが可能となります。
テーマは継承することによって要素を変えていくことができます。
デフォルトでこんな感じのテーマが作られて皆さん使っていると思います。
今回はTheme.AppCompat.Light.DarkActionBarを継承しています。
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
ではこの継承しているTheme.AppCompat.Light.DarkActionBarは何者でしょうか?
これは実際にはこうなっておりBase.Theme.AppCompat.Light.DarkActionBarを継承しています。
<style name="Theme.AppCompat.Light.DarkActionBar" parent="Base.Theme.AppCompat.Light.DarkActionBar"/>
Base.Theme.AppCompat.Light.DarkActionBarはどうなっているかというと、Base.Theme.AppCompat.Lightを継承しているようです。
<style name="Base.Theme.AppCompat.Light.DarkActionBar" parent="Base.Theme.AppCompat.Light">
<item name="actionBarPopupTheme">@style/ThemeOverlay.AppCompat.Light</item>
<item name="actionBarWidgetTheme">@null</item>
<!-- 省略 -->
</style>
Base.Theme.AppCompat.Lightは、AndroidのAlternative resourceの仕組みを利用しています。今回はAndroid5.0以上であればvaluesディレクトリにあるvalues.xmlではなく、values-v21やvalues-v22やvalues-v23にあるvalues.xmlのstyleを利用します。そのためBase.Theme.AppCompat.Lightは4つ定義されています。
またそれぞれのBase.Theme.AppCompat.Lightで継承しているstyleが違うので、もうとてもじゃないですが、追えません。
そこで**グラフで作ってしまえば分かるのでは、、**ということでxmlからGraphvizのdotファイルを自動生成してグラフを作ってみました。
非常に見難いのですが、全体像を出すとこんな感じになります。
継承とAlternative resourceの仕組みを上手く使うことでバージョンごとに分けたり、全部で使うものをvalues/themes.xml内で定義してそれを継承したりして、うまくやっているようです。
があまり追えません。。
AppCompat系の全体の画像は以下になります。(めっちゃでかいです。)
https://github.com/takahirom/android-theme-and-style-graph/raw/95b27f29567de0833f4e0475421086a35efd4520/output.png
またpdfは以下になります。
https://github.com/takahirom/android-theme-and-style-graph/raw/master/output/appcompat.pdf
生成のスクリプトなどはここにおいてあります。(動けばよかったのでソース汚いです、、)
https://github.com/takahirom/android-theme-and-style-graph
まとめ
正直図にしてもよくわからなかったですが、テーマの継承をうまくたくさん利用してバージョン対応している事がわかりました。
ThemeOverlayなどの色んなテーマやスタイルの仕組みを探ったりする時にもしかすると役立つかもしれません。