見出し画像

Android Studioでスタイル/テーマの継承関係を表示する小技

要約

継承関係を辿りたいスタイルリソースにテキストカーソルを合わせ、macOSの場合は [F1] 、Windowsの場合は [Ctrl] + [Q] を2回押すと、Documentation tool windowにそのスタイルリソースの継承関係が表示されます。

Documentation tool windowの表示

Documentation tool windowにフォーカスを当てた状態でmacOSの場合は [Command] + [F] 、Windowsの場合は [Ctrl] + [F] を押すと検索窓が現れるので、属性名や属性値で検索することができます。

Documentation tool windowでの検索

はじめに

Androidアプリ(Viewベース)の開発中に「このスタイル/テーマにおいて、あの属性にはどんな値が適用されているのか」ということを調べる必要性が生じることがあります。

例えば、 "Theme.MaterialComponents.Light.NoActionBar.Bridge" の "android:windowAnimationStyle" に適用されている値を調べるケースです。"android:windowAnimationStyle" は "Theme.MaterialComponents.Light.NoActionBar.Bridge" には直接指定されていないため、親を順番に辿って指定箇所を探さなければなりません。実際に継承関係を辿ってみると、 "android:windowAnimationStyle" は16階層も上に遡ったところにあるスタイルリソース "Theme.Material.Light" で指定されていました。

"Theme.MaterialComponents.Light.NoActionBar.Bridge" の継承関係:

Theme.Material.Lightandroid:Theme.Material.Light.NoActionBarPlatform.V25.AppCompat.LightPlatform.AppCompat.LightBase.V7.Theme.AppCompat.LightBase.V21.Theme.AppCompat.LightBase.V22.Theme.AppCompat.LightBase.V23.Theme.AppCompat.LightBase.V26.Theme.AppCompat.LightBase.V28.Theme.AppCompat.LightBase.Theme.AppCompat.LightTheme.AppCompat.LightPlatform.MaterialComponents.LightBase.V14.Theme.MaterialComponents.Light.BridgeBase.Theme.MaterialComponents.Light.BridgeTheme.MaterialComponents.Light.BridgeTheme.MaterialComponents.Light.NoActionBar.Bridge

"Theme.Material.Light" の定義:

<style name="Theme.Material.Light" parent="Theme.Light">
	(中略)
	<item name="windowAnimationStyle">@style/Animation.Material.Activity</item>

core/res/res/values/themes_material.xml - platform/frameworks/base - Git at Google より引用)
※Androidプラットフォーム内のXMLで定義されているため、属性名 "windowAnimationStyle" の先頭から "android:" が省略されています

継承関係を辿ること自体は、Android StudioのGo to Declaration機能(macOSの場合は [Command] + [B]、Windowsの場合は [F12])でparentの定義に飛んだり、XMLファイル上でドット表記による継承の親を探したりすれば可能ですが、非常に面倒な作業です。

でも実は、Android Studioにはこの作業を圧倒的に楽にしてくれる小技があるんです!

Android Studioでスタイル/テーマの継承関係を表示する小技

まず、継承関係を辿りたいスタイルリソースにテキストカーソルを合わせます。

継承関係を辿りたいスタイルリソースにテキストカーソルを合わせる

次に、macOSの場合は [F1] 、Windowsの場合は [Ctrl] + [Q] を押します。すると、Quick Documentation機能のポップアップが表示されます。

Quick Documentation機能のポップアップ

この状態でもう一度macOSの場合は [F1] 、Windowsの場合は [Ctrl] + [Q] を押すと、今度はAndroid Studioの右側ペインにDocumentation tool windowが表示されます。

Documentation tool windowの表示

Documentation tool windowの内容例:

Theme.MaterialComponents.Light.NoActionBar.Bridge:
    windowActionBar = false
    windowNoTitle = true

  Inherits from: @style/Theme.MaterialComponents.Light.Bridge:

  Inherits from: @style/Base.Theme.MaterialComponents.Light.Bridge:

  Inherits from: @style/Base.V14.Theme.MaterialComponents.Light.Bridge:
    badgeStyle = @style/Widget.MaterialComponents.Badge => @style/Widget.MaterialComponents.Badge
    bottomAppBarStyle = @style/Widget.MaterialComponents.BottomAppBar => @style/Widget.MaterialComponents.BottomAppBar
    chipGroupStyle = @style/Widget.MaterialComponents.ChipGroup => @style/Widget.MaterialComponents.ChipGroup
    chipStandaloneStyle = @style/Widget.MaterialComponents.Chip.Entry => @style/Widget.MaterialComponents.Chip.Entry
    chipStyle = @style/Widget.MaterialComponents.Chip.Action => @style/Widget.MaterialComponents.Chip.Action
    circularProgressIndicatorStyle = @style/Widget.MaterialComponents.CircularProgressIndicator => @style/Widget.MaterialComponents.CircularProgressIndicator
    colorOnBackground = @color/design_default_color_on_background #000000
    colorOnError = @color/design_default_color_on_error #FFFFFF
    colorOnPrimary = @color/design_default_color_on_primary #FFFFFF
    colorOnPrimarySurface = ?attr/colorOnPrimary #FFFFFF
    colorOnSecondary = @color/design_default_color_on_secondary #000000
    colorOnSurface = @color/design_default_color_on_surface #000000
    colorPrimarySurface = ?attr/colorPrimary #2B3A5F
    colorPrimaryVariant = @color/design_default_color_primary_variant #3700B3
    colorSecondary = @color/design_default_color_secondary #03DAC6
    colorSecondaryVariant = @color/design_default_color_secondary_variant #018786
    colorSurface = @color/design_default_color_surface
    ...

このウィンドウには、上位のスタイルリソースから引き継がれて現在のスタイルリソースに適用されている属性名と属性値の組み合わせが表示されています。親やその親、さらにその親、と継承関係を辿る作業をAndroid Studioがやってくれるんです!

結構な分量があるため目で探すのは結構大変ですので、キーワード検索を活用しましょう。Documentation tool windowの領域内をマウスでクリックしてウィンドウをアクティブにした状態で、macOSの場合は [Command] + [F] 、Windowsの場合は [Ctrl] + [F] を押すと検索窓が現れます。そこに調べたい属性名を入力して検索すると、継承した属性の値を見つけることができます。

Documentation tool windowでの検索

上図から、"android:windowAnimationStyle" 属性の値は "@style/Animation.Material.Activity" であることがわかります。

属性値として指定されたスタイルリソースの中身を深堀り調査する方法

上述した方法はスタイルリソースのparent属性やスタイル名のドット表記で継承された継承は辿ってくれますが、スタイルの属性として定義された別のスタイルの継承関係までは辿ってくれません。

例として、もう一度 "Theme.Material.Light" の定義を見てみましょう。

<style name="Theme.Material.Light" parent="Theme.Light">
	(中略)
	<item name="windowAnimationStyle">@style/Animation.Material.Activity</item>

core/res/res/values/themes_material.xml - platform/frameworks/base - Git at Google より引用)

スタイルリソース "Theme.Material.Light" の属性 "windowAnimationStyle" に対して "@style/Animation.Material.Activity" という値が定義されています。
"@style/Animation.Material.Activity" はスタイルリソースですので、さらにそのスタイルで直接指定された属性値や親から継承された属性値が存在します。しかし、前節の例のように、Documentation tool windowはそこまで表示してくれません。

では、どうすれば "@style/Animation.Material.Activity" の継承関係を表示できるかというと、"Animation.Material.Activity" が親となるような仮のスタイルリソースを記述し、macOSの場合は [F1] 、Windowsの場合は [Ctrl] + [Q] を2回押してDocumentation tool windowを表示するだけです。

<!-- 仮のスタイルリソース -->
<style name="tmp" parent="android:Animation.Material.Activity" />

※ "Animation.Material.Activity" はAndroidプラットフォーム内のXMLで定義されているため、アプリから参照するには先頭にパッケージ名 "android:" を付加する必要があります。なお、アットマークやリソースタイプを省略せずに "@android:style/Animation.Material.Activity" と書くこともできます。

Document tool windowで "@android:style/Animation.Material.Activity" の継承関係を表示

(おまけ)便利だけど見つけづらい小技?

この小技は誰かから教えてもらったわけではなく、アプリ開発中にたまたま発見しました。日本語・英語の両方で検索してみたのですが、次のStack Overflowしか出てきませんでした。

(おまけ)Android Studioのソースコード

Android Studio自体はオープンソースになっているため、今回紹介したスタイルリソースのDocumentation tool windowの実装を見ることができます。
Android Code Searchで"Inherits from:"というキーワードで検索してみたら、次のソースコードがヒットしました。

private void displayStyleValues(HtmlBuilder builder, ItemInfo item, ResourceItemResolver resolver, StyleResourceValue styleValue) {
    (中略)
    styleValue = resolver.getParent(styleValue);
    if (styleValue != null) {
        builder.newline();
        builder.add("Inherits from: ").add(styleValue.getResourceUrl().toString()).add(":").newline();
    }

AndroidJavaDocRenderer.java - Android Code Search より引用)

アプリ内やAndroidフレームワークのスタイルリソースを解析し、HTMLに出力した結果をDocument tool windowに表示しているようです。

宣伝

NTTレゾナントテクノロジーでは一緒に働いてくれるAndroid/iOSアプリエンジニアを募集中です。もし興味がありましたら採用ページを是非ご覧ください。

(文:NTTレゾナントテクノロジー 西添)


いいなと思ったら応援しよう!