はじめに
- Android Studio 4.1 でテンプレートアプリケーションに設定されているテンプレートが Material Design Component (以下MDC)になりました。記事
- ということでそろそろAndroidアプリの標準的ThemeはMDCに準拠していかないとならないなと思っていますが、そうもいかないよーと思っていたりもします。
- ただ、MDCに適応していくことで実装上の利点なんかもあるので、そういう意味では使いやすい部分から移行して行きたいところだったり。
- よくある AppCompat時代のButtonコンポーネントを、MDC対応Buttonコンポーネントにする方法をまとめておきます。
よくあるAppCompatのButtonって?
想定
- iOSと同じようなデザインでと言われ、角丸、単色(通常色、選択色、無効色)のボタンを用意する感じです
(もちろん
RippleEffect
は使っていないよ。)
用意する
- アプリのテーマは
"Theme.AppCompat.DayNight.DarkActionBar"
あたりを設定と想定
ボタン色
colors.xml
<color name="default_button_color">#ff0000ff</color>
<color name="highlight_button_color">#ff007Fff</color>
<color name="disable_button_color">#550000ff</color>
ボタンの選択状態と角丸設定(通常用)
shape_corner_radius_4dp_button_default_background.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="4dp" />
<solid android:color="@color/default_button_color" />
</shape>
ボタンの選択状態と角丸設定(選択用)
shape_corner_radius_4dp_button_highlight_background.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="4dp" />
<solid android:color="@color/disable_button_color" />
</shape>
ボタンの選択状態と角丸設定(選択用)
shape_corner_radius_4dp_button_disable_background.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="4dp" />
<solid android:color="@color/highlight_button_color" />
</shape>
ボタンのselector設定
- 通常・選択・無効の状態を切り替えさせる為に
drawable
フォルダ内に用意
selector_default_button.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/shape_default_button" android:state_enabled="true" android:state_pressed="false" />
<item android:drawable="@drawable/shape_default_button_highlighted" android:state_pressed="true" />
<item android:drawable="@drawable/shape_default_button_disabled" android:state_enabled="false" />
</selector>
ボタンコンポーネント
<Button
android:id="@+id/button_first"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/next"
android:textColor="@color/white"
android:background="@drawable/selector_default_button"
・・・
/>
こんな感じ
何が嫌か
- ボタンの角丸サイズ違いや、色違いで
drawable
のリソースが増えていくのが非常に煩わしいところですね。
ButtonだけをMDC対応した場合
- まずは MDCのライブラリは必要なのでgradleで取り込んでおきましょう。
build.gradle
dependencies {
・・・
implementation 'com.google.android.material:material:1.2.1'
}
MDC用 Theme を用意
- MDC には AppCompatに存在していない必須となる設定値があるので、Button用にThemeを作成します。
-
colorOnPrimary
colorPrimary
colorOnSurface
は新しく必要ないろ定義です。- 文字色の指定ですので、任意の色を指定してあげてください。
theme.xml
<!-- アプリ全体でMaterialComponentを適応できれば不要になるTheme -->
<style name="MDCButtonTheme" parent="Theme.MaterialComponents">
<item name="colorOnPrimary">@color/base_text_color</item>
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorOnSurface">@color/base_text_color</item>
</style>
MDC用 Style を用意
-
"@style/Widget.MaterialComponents.Button.UnelevatedButton"
は MDCで用意された、高さを表現させない場合のStyle定義 -
insetTop
とinsetBottom
は MDCのボタンに標準で設定されている Inset値(タッチ領域だけを広げる設定)を0に設定しています。
style.xml
<style name="MDCButtonStyle" parent="@style/Widget.MaterialComponents.Button.UnelevatedButton">
<item name="android:insetTop">0dp</item>
<item name="android:insetBottom">0dp</item>
</style>
ボタンのselector設定
- 通常・選択・無効の状態を切り替えさせる為に
color
フォルダ内に用意 - 配置先が
drawable
からcolor
にかわり、設定も色だけの設定にしています
selector_default_button.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@color/default_button_color" android:state_enabled="true" android:state_pressed="false" />
<item android:color="@color/default_button_highlight_color" android:state_pressed="true" />
<item android:color="@color/disable_button_color" android:state_enabled="false" />
</selector>
ボタンコンポーネント
-
Button
からMaterialButton
に変更 - Theme と Style は必須となるので設定
- MDCのStyleにボタンの角丸
4dp
が設定されているので記述していませんが、MDCではXMLからcornerSize
を利用する事で、角丸の値を設定できます。
<com.google.android.material.button.MaterialButton
android:id="@+id/button_first"
style="@style/MDCButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:backgroundTint="@color/selector_default_button"
android:text="@string/next"
android:textColor="@color/white"
android:theme="@style/MDCButtonTheme"
・・・
/>
こんな感じ
ほどんと同じボタンが出来上がりました。
- MDC のButtonを利用する事で、角丸や色の設定ごとにDrawableを増やす必要がなくなるので便利ですね。
まとめ
- MDCへの切り替えは早めにしたいが、なかなか難しい場合、Buttonだけとかでも切り替えていってみよう。
- MDCのButtonを利用する事で、無駄にリソースを作る必要がなくなります!
- 本当はアプリのThemeを切り替えられるのがいいんでしょうけど