iT邦幫忙

2022 iThome 鐵人賽

DAY 12
1

前言

為 selection controls components 最後一個元件,與 slider、checkboxes 在設計上都非常簡潔,一樣也是實作與設計一起講解

image alt

大綱

  • Design
    • Usage
    • Behavior
    • State
  • Implementation
    • Using
    • Key properties
    • Style

Design

Usgae

是一個多個選項的列表,但只能讓用戶選擇其中之一,不能進行複選

使用情境上

  • 在多個選項清單中做單個選擇
  • 列出所有可供選擇的項目

原則

  • 普遍性的 : 不要有太浮誇的設計,呈現普遍看到的樣式讓用戶一眼就能理解
  • 可辨識的 : 被選中的狀態比起其他未被選擇的樣式更加顯眼,讓用戶能看出差異
  • 有效率的 : 讓選擇情境上更加快速直覺與效率

何時使用?

適用在多個選擇的情境,但只能讓用戶選擇其中之一。與外觀上相似的 checkboxes 比較的話,最大差異在於複選與單選,如圖下所示

Behavior

讓用戶從一組選項中選出一個選項,只要選擇其中一個時,就會立刻取消另一個。當用戶需要查看所有可用選項時,如果選項太多,應該使用 Drop down menu 將其折疊隱藏,能節省更多空間

image alt

State

狀態設計上,注重在 checked 與 unchecked,點擊時出現 ripple ; 點選後則會將 icon 用主題顏色填滿,代表著已被選取,關閉狀態則透過顏色變化來傳達

image alt

Implementation

實作上,Material Design 都幫我們設置好了,直接使用就可

Using

Group Radio Buttons

設計上,我們希望是單選功能。實作上就要透過 Group Radio Buttons 來實現,被放在群組中的 Radio buttons 之間會互相影響,一旦有一個項目被選擇了,另一個之前被選的項目就會被取消

image alt

in layout

透過一個 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>

in code

// 透過 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
}

Key properties

Radio button


與 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"
    />

Text label

Style

Custom Style

上面有稍微提到過如何自定義顏色,這邊再整理一下

預設未選狀態顏色是 ?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 來設置

in 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>

in layout

<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 當中去套用

in 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 方便大家參考


上一篇
Day 11 - Checkboxes (Design & Implementation)
下一篇
Day 13 - Floating action button (Design)
系列文
從 Google Material Design Components 來了解與實作 Android 的 UI/UX 元件設計30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言