ThemeとStyleの違いについてよく分からなかったので調べてみました。
下記事によるとThemeはアプリ全体など広範囲に適用するものでStyleは個別のパーツに設定するもののようです。
記事を見た感じApplicationやActivityにはThemeを利用、Buttonなどの個別のViewにはStyleを使っているようでした。
試しにStyleを作ってTextViewにセットしてみました。
<?xml version="1.0" encoding="utf-8"?> <resources> <style name="TestStyle"> <item name="android:textColor">#00FF00</item> </style> </resources>
<TextView android:id="@+id/textview_first" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/hello_first_fragment" style="@style/TestStyle" app:layout_constraintBottom_toTopOf="@id/button_first" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" />
アプリを起動した所、無事に色変更が反映されました。
このStyleですがthemes.xmlに移動しても問題なく動きました。
<style name="TestStyle"> <item name="android:textColor">#00FF00</item> </style>
逆にstyleをandroid:themeで指定した場合も動かす事ができました。
<TextView android:id="@+id/textview_first" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/hello_first_fragment" android:theme="@style/TestStyle" app:layout_constraintBottom_toTopOf="@id/button_first" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" />
優先度を調べるためにandroid:themeとstyleの両方にセットした所styleが優先されるようでした。
<resources> <style name="TestStyle"> <item name="android:textColor">#00FF00</item> </style> <style name="TestStyle2"> <item name="android:textColor">#0000FF</item> </style> </resources>
<TextView android:id="@+id/textview_first" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/hello_first_fragment" android:theme="@style/TestStyle2" style="@style/TestStyle" app:layout_constraintBottom_toTopOf="@id/button_first" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" />
android:themeですがTextViewの親Viewにセットしても反映されました。
ただstyleは反映されませんでした。
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:theme="@style/TestStyle" style="@style/TestStyle2" tools:context=".FirstFragment"> </androidx.constraintlayout.widget.ConstraintLayout>
親と子の両方にandroid:themeをセットした場合、子供の方が優先されます。
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:theme="@style/TestStyle" tools:context=".FirstFragment"> <TextView android:id="@+id/textview_first" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/hello_first_fragment" android:theme="@style/TestStyle2" app:layout_constraintBottom_toTopOf="@id/button_first" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout>
それとTextViewではtextAppearanceという属性でもStyleをセットできます。
こちらはandroid:themeより低い優先度になります。
<TextView android:id="@+id/textview_first" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/hello_first_fragment" android:textAppearance="@style/TestStyle2" app:layout_constraintBottom_toTopOf="@id/button_first" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" />
ThemeやStyleですが親の指定も可能です。
下のようにparentで親を指定します。
親の持つitemは子供側で上書きする事もできます。
<style name="TestStyle2" parent="TestStyle"> <item name="android:textColor">#0000FF</item> </style>
下のように親を.でつなげることでparentなしで継承できます。
<style name="TestStyle.TestStyle2"> </style>
styleですがAlertDialogなどへの設定も可能です。
<style name="MyDialogAlert" parent="android:Theme.Material.Light.Dialog.Alert"> <item name="android:textColor">#FF0000</item> </style>
第2引数はthemeResIdというパラメータですが、themeではなくstyleを渡すほうが良さそうです。
AlertDialog.Builder(this, R.style.MyDialogAlert).setTitle("test") .setPositiveButton("OK", null).show()
それとtheme内で下のように指摘すればすべてのAlertDialogにstyleを一括適用する事ができます。
<item name="android:alertDialogTheme">@style/MyDialogAlert</item>