はじめに
StyleはViewの外観を指定する属性(attribute)の集まりです。
そのため、Viewの属性の共通化したい時に使っていると思います。
ただ最近「レイアウトパラメータってStyleに書いていいのかなぁ」と疑問に思うことがありました。
※ レイアウトパラメータと言っているのは、ViewのXMLに記述する android:layout_...
から始まる属性のことです
<style name="Widget.AppTheme.Button.Green"> <item name="android:layout_width">wrap_content</item> // 書いていいの? <item name="android:layout_height">wrap_content</item> // 書いていいの? <item name="backgroundTint">@color/background_tint_green</item> <item name="android:textColor">@android:color/white</item> </style>
もちろん書くのは問題ないし、同じレイアウトパラメータを書く手間も減ります。
でもこの記事を読んでから疑問に思うようになりました。
気になった点
A style is a collection of view attribute values. https://medium.com/androiddevelopers/android-styling-themes-vs-styles-ebe05f917578
日本語訳すると「StyleはViewの属性の集まり」なので、これまでのStyleの説明と何ら変わらない気がします。
しかし view attribute values
は ViewのXML attributesに定義されているものを指しているのかなと思いました。
そのように考えるとレイアウトパラメータの android:layout_width
や android:layout_height
はViewのXML attributesには定義されていないので、Styleに書く対象ではないと考えることもできます。
ちなみに android:layout_width
と android:layout_height
はViewGroup.LayoutParamsのXML attributesに定義されています。
そのため android:layout_width
と android:layout_height
はViewの属性というより、ViewGroup.LayoutParamsの属性といった方がより正確かもしれません。
どうするべきか
StyleにLayoutParamsを書くことは問題ありません。
ただ意識すべきことが2点あると思います。
- ViewのXMLに書いた
android:layout_...
の値をチェックしてLayoutParamsを決定するのは親のレイアウトであること(参考:レイアウト | Android Developers) - ViewGroup.LayoutParamsを継承するレイアウトごとの属性があること
1.について
ViewはLayoutParamsを持っていますが、どんなLayoutParamsがセットされるかは親のレイアウトによって変わります。
レイアウトパラメータの説明画像を見てもわかるように、親のレイアウトが LinearLayout
なら LinearLayout.LayoutParams
がセットされるし、親のレイアウトが ConstraintLayout
なら ConstraintLayout.LayoutParams
がセットされます。
2.について
例えば FrameLayout.LayoutParams
には android:layout_gravity
の属性がありますが、 RelativeLayout.LayoutParams
にはありません。
方針案
主に「2. ViewGroup.LayoutParamsを継承するレイアウトごとの属性があること」によって、レイアウトパラメータをStyleに書くべきではないと思っています。
例えば android:layout_gravity
は FrameLayout
内では有効な属性ですが、 RelativeLayout
内では無効な属性になってしまいます。
また、言い換えるとStyleにレイアウトパラメータを書くということは、使用できる親のレイアウトを制限していると言えるかもしれません。
そのため、複数の種類のレイアウトで使う想定があるなら、レイアウトパラメータをStyleに書くべきではないと思っています。
(一方で、レイアウトの種類ごとにStyleを作るという方針もありかもしれません)
まとめ
android:layout_...
から始まるレイアウトパラメータは、親のレイアウトによって有効な属性が違う- 複数の種類のレイアウトで一つのStyleを使うなら、レイアウトパラメータをStyleに書かない方が良さそう