為 selection controls components 最後一個元件,與 slider、checkboxes 在設計上都非常簡潔,一樣也是實作與設計一起講解
是一個多個選項的列表,但只能讓用戶選擇其中之一,不能進行複選
適用在多個選擇的情境,但只能讓用戶選擇其中之一。與外觀上相似的 checkboxes 比較的話,最大差異在於複選與單選,如圖下所示
讓用戶從一組選項中選出一個選項,只要選擇其中一個時,就會立刻取消另一個。當用戶需要查看所有可用選項時,如果選項太多,應該使用 Drop down menu 將其折疊隱藏,能節省更多空間
狀態設計上,注重在 checked 與 unchecked,點擊時出現 ripple ; 點選後則會將 icon 用主題顏色填滿,代表著已被選取,關閉狀態則透過顏色變化來傳達
實作上,Material Design 都幫我們設置好了,直接使用就可
設計上,我們希望是單選功能。實作上就要透過 Group Radio Buttons 來實現,被放在群組中的 Radio buttons 之間會互相影響,一旦有一個項目被選擇了,另一個之前被選的項目就會被取消
透過一個 Group 包裹所有的 RadioButtons,而 Group 本身是 Linearlayout 的子類,所以能使用android:orientation="vertical"
來設置方向,預設上是 vertical。當中還有一個android:checkedButton"
屬性可以來預設初始狀態被選取的 RadioButton
<RadioGroup
android:id="@+id/radioGroup"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:checkedButton="@id/radio_button_1"
>
<com.google.android.material.radiobutton.MaterialRadioButton
android:id="@+id/radio_button_1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="radio_button_1" />
<com.google.android.material.radiobutton.MaterialRadioButton
android:id="@+id/radio_button_2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="radio_button_2" />
<com.google.android.material.radiobutton.MaterialRadioButton
android:id="@+id/radio_button_3"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:useMaterialThemeColors="false"
android:text="radio_button_3" />
<com.google.android.material.radiobutton.MaterialRadioButton
android:id="@+id/radio_button_4"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:useMaterialThemeColors="false"
android:text="radio_button_4" />
<com.google.android.material.radiobutton.MaterialRadioButton
android:id="@+id/radio_button_5"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="radio_button_5" />
</RadioGroup>
// 透過 radiobutton group 能拿到當前被 checked 的 button id
val checkedRadioButtonId = radioGroup.checkedRadioButtonId
// 透過 radioGroup 為每個 radiobutton 設置監聽事件
radioGroup.setOnCheckedChangeListener { group, checkedId ->
when(checkId){
R.id.radio_button_1 -> // do something for button 1
R.id.radio_button_2 -> // do something for button 2
R.id.radio_button_3 -> // do something for button 3
R.id.radio_button_4 -> // do something for button 4
R.id.radio_button_5 -> // do something for button 5
}
}
// 自行手動更改 RadioButton 的選取狀態
radioButton.isChecked = true
// 除了能透過 Group 對整體 RadioButtons 設置監聽外,也能單獨在元件上設置
radioButton.setOnCheckedChangeListener { buttonView, isChecked
// if checked is true , do checked function
// if checked is false , do cancel checked function
}
與 checkboxes 的相同設置相同,預設上都綁定了 theme color
預設未選狀態顏色是 ?attr/colorOnSurface
(unchecked)
選中狀態顏色是 ?attr/colorSecondary
(checked)
如果不想使用預設的顏色,可以將綁定 Theme 的設定關掉 app:useMaterialThemeColors="false"再透過 android:buttonTint 設定想要的顏色,記得設置 color 要使用 selector
<RadioButton
...
app:useMaterialThemeColors="false"
android:buttonTint="@color/radio_button_selector"
/>
上面有稍微提到過如何自定義顏色,這邊再整理一下
預設未選狀態顏色是 ?attr/colorOnSurface
(unchecked)
選中狀態顏色是 ?attr/colorSecondary
(checked)
<style name="Widget.App.RadioButton" parent="Widget.MaterialComponents.CompoundButton.RadioButton">
<item name="materialThemeOverlay">@style/ThemeOverlay.App.RadioButton</item>
<item name="android:padding">10dp</item>
<item name="android:textSize">20sp</item
</style>
<style name="ThemeOverlay.App.RadioButton" parent="">
<item name="colorOnSurface">@color/lightGreen</item>
<item name="colorSecondary">@color/lightYellow</item>
</style>
注意 :如果設定的主題風格檔,元件沒有隨之變化,是因為沒有用 material 系列的元件。例如如果使用一般的 RadioButton,是不會起作用的,要使用
com.google.android.material.radiobutton.MaterialRadioButton
,這是因為有些元件在 Material Design 還沒出現之前就有了,所以在基礎設置上並沒有相容,就要使用最新的 material Design 系列的元件才能成功設置
若版本上沒辦法使用最新的元件,或是不想透過主題來變換顏色,就可以用上述剛剛提到的 android:buttonTint
設定想要的顏色,記得要透過 selector 來設置
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@color/lightBrown" android:state_checked="true"/>
<item android:color="@color/darkGrey" android:state_checked="false"/>
<item android:color="@color/lightBrown"/>
</selector>
<RadioButton
android:id="@+id/radio_button_5"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:useMaterialThemeColors="false"
android:padding="10dp"
android:buttonTint="@color/radio_button_selector"
android:text="radio_button_5" />
也可以把 android:buttonTint
寫入 style 當中去套用
<style name="Widget.App.RadioButtonButtonTint" parent="Widget.MaterialComponents.CompoundButton.RadioButton">
<item name="buttonTint">@color/radio_button_selector</item>
<item name="android:padding">10dp</item>
<item name="android:textSize">20sp</item>
</style>
Selection Controls Components 就到這邊告一段落了,在設計與實作上都非常的簡潔與簡單。重點在於 checked 與 unchecked 的設計應該讓用戶能快速辨識,避免過於複雜
適用在多種選擇且只能讓用戶單選的情境,與 checkboxes 最大的差別在於單選與多選。一旦用戶選擇其中一項後,前一項選擇過的就會跟著取消,在群組中的 RadioButtons 一次只能有一個被選取
若對實作還是有點不懂的,這邊提供我的 Github 方便大家參考