MDC-101 Android:Material Design 元件 (MDC) 基本概念 (Kotlin)

1. 簡介

logo_components_color_2x_web_96dp.png

Material 元件 (MDC) 可協助開發人員實作 Material Design。MDC 是由 Google 工程師和使用者體驗設計師團隊打造,提供數十種精美且實用的 UI 元件,適用於 Android、iOS、網頁和 Flutter.material.io/develop

什麼是 Android 適用的 Material Design 和 Material 元件?

Material Design 是用於打造大膽精美的數位產品的系統。產品團隊只要遵循一致的原則和元件組合,將樣式、品牌宣傳、互動和動畫一貫化,就能實現最大的設計潛力。

對於 Android 應用程式,Android Material 元件 (MDC Android) 會將設計和工程與元件庫相結合,以便為應用程式維持一致性。隨著 Material Design 系統不斷演進,這些元件也會持續更新,確保像素完美實作一致,並符合 Google 的前端開發標準。MDC 也可使用於網頁、iOS 和 Flutter。

在本程式碼研究室中,您將使用數個 MDC Android 元件建構登入頁面。

建構項目

這個程式碼研究室是四個程式碼研究室中的第一個,將引導您建構名為 Shrine 的應用程式,這是一款販售服飾和家居用品的電子商務 Android 應用程式。示範如何使用 MDC Android 自訂元件,以反映任何品牌或風格。

在本程式碼研究室中,您會建構 Shrine 的登入頁面,其中包含:

  • 兩個文字欄位,一個用於輸入使用者名稱,另一個則用於密碼
  • 兩個按鈕,一個是「取消」,另一個是「下一步」
  • 應用程式名稱 (Shrine)
  • Shrine 標誌的圖片

4cb0c218948144b4.png

本程式碼研究室中的 MDC Android 元件

  • 文字欄位
  • 按鈕

軟硬體需求

  • 對 Android 開發作業有基本瞭解
  • Android Studio (如果尚未安裝,請按這裡下載)
  • Android 模擬器或裝置 (可透過 Android Studio 取得)
  • 程式碼範例 (請參閱下一個步驟)

你對建立 Android 應用程式的經驗程度為何?

初級 中級 適合

2. 設定開發環境

啟動 Android Studio

開啟 Android Studio 時,畫面上會顯示標題為「Welcome to Android Studio」的視窗。不過,如果這是您第一次啟動 Android Studio,請按照 Android Studio 設定精靈步驟,輸入預設值。這個步驟可能需要幾分鐘的時間來下載和安裝必要檔案,因此您可以在後續部分中,繼續在背景執行。

下載範例程式碼研究室應用程式

範例應用程式位於 material-components-android-codelabs-101-starter/kotlin 目錄中。

...或從 GitHub 複製

如要從 GitHub 複製本程式碼研究室,請執行下列指令:

git clone https://github.com/material-components/material-components-android-codelabs
cd material-components-android-codelabs/
git checkout 101-starter

在 Android Studio 中載入範例程式碼

  1. 設定精靈完成後,系統會顯示「Welcome to Android Studio」視窗,請按一下「Open an existing Android Studio project」。前往您安裝程式碼範例的目錄,然後選取 kotlin -> Shrine (或在電腦上搜尋 shrine),即可開啟運送專案。
  2. 請稍候,讓 Android Studio 建構及同步處理專案,Android Studio 視窗底部的活動指標會顯示這項作業的進度。
  3. 此時,Android Studio 可能會引發部分建構錯誤,因為缺少 Android SDK 或建構工具 (如下所示)。請按照 Android Studio 中的操作說明安裝/更新這些項目,並同步處理專案。

KzoYWC1S7Se7yL8igi1vXF_mbVxAdl2lg5kb7RODrsVpEng0G6U3NK1Qnn0faBBZd2u71yMXioy9tD-7fv3NXvVO4N3EtMMeWDTmqBMMl6egd9R5uXX0T_SKmahbmRor3wZZHX0ByA

新增專案依附元件

專案需要依附 MDC Android 支援程式庫。您下載的程式碼範例中應該已經包含這個依附元件,但建議您執行下列步驟確認。

  1. 前往 app 模組的 build.gradle 檔案,確認 dependencies 區塊包含 MDC Android 的依附元件:
api 'com.google.android.material:material:1.1.0-alpha06'
  1. (選用) 視需要編輯 build.gradle 檔案,新增下列依附元件並同步處理專案。
dependencies {
    api 'com.google.android.material:material:1.1.0-alpha06'
    implementation 'androidx.legacy:legacy-support-v4:1.0.0'
    implementation 'com.android.volley:volley:1.1.1'
    implementation 'com.google.code.gson:gson:2.8.5'
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.21"
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test:core:1.1.0'
    androidTestImplementation 'androidx.test.ext:junit:1.1.0'
    androidTestImplementation 'androidx.test:runner:1.2.0-alpha05'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0-alpha05'
}

執行範例應用程式

  1. 確認「Run / Play」按鈕左側的建構設定為 app
  2. 按下綠色的「Run/Play」按鈕,即可建構並執行應用程式。
  3. 在「Select Deployment Target」視窗中,如果可用裝置已列出「Android 裝置」,請跳至步驟 8。否則,請按一下「Create New Virtual Device」
  4. 在「Select Hardware」畫面中,選取手機裝置 (例如 Pixel 2),然後按一下「Next」
  5. 在「System Image」畫面中選取最新的 Android 版本 (最好是最高 API 級別)。如果尚未安裝,請按一下畫面中顯示的「Download」(下載) 連結並完成下載。
  6. 點選「下一步」
  7. 在「Android 虛擬裝置 (AVD)」畫面中,保留原有的設定,然後按一下「Finish」
  8. 從部署目標對話方塊中選取「Android 裝置」
  9. 按一下 [確定]。
  10. Android Studio 會建構應用程式、部署應用程式,並在目標裝置上自動開啟應用程式。

大功告成!Shrine 登入頁面的範例程式碼應會在模擬器中執行。你應該會看到「Shrine」名稱,以及下方的 Shrine 標誌。

e7ed014e84755811.png

讓我們來看看程式碼。我們在程式碼範例中提供簡易的 Fragment 導覽架構,用來顯示片段並在片段之間導覽。

shrine -> app -> src -> main -> java -> com.google.codelabs.mdc.kotlin.shrine 目錄中開啟 MainActivity.kt。其中應包含以下內容:

MainActivity.kt

package com.google.codelabs.mdc.kotlin.shrine

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment

class MainActivity : AppCompatActivity(), NavigationHost {

   override fun onCreate(savedInstanceState: Bundle?) {
       super.onCreate(savedInstanceState)
       setContentView(R.layout.shr_main_activity)

       if (savedInstanceState == null) {
           supportFragmentManager
                   .beginTransaction()
                   .add(R.id.container, LoginFragment())
                   .commit()
       }
   }

   override fun navigateTo(fragment: Fragment, addToBackstack: Boolean) {
       val transaction = supportFragmentManager
               .beginTransaction()
               .replace(R.id.container, fragment)

       if (addToBackstack) {
           transaction.addToBackStack(null)
       }

       transaction.commit()
   }
}

此活動會顯示 shr_main_activity.xml 中定義的 R.layout.shr_main_activity 版面配置檔案。

您可以看到,在 onCreate(), 中,MainActivity.kt 會啟動 Fragment 交易,以便顯示 LoginFragment。在本程式碼研究室中,我們將修改 LoginFragment。活動也會實作 navigateTo(Fragment) 方法,該方法在 NavigationHost 中定義,可讓任何片段前往其他片段。

在活動檔案中,按下 Command + 按一下 (或 Control + 滑鼠) shr_main_activity 開啟版面配置檔案,或是前往 app -> res -> layout -> shr_main_activity.xml 的版面配置檔案。

shr_main_activity.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:tools="http://schemas.android.com/tools"
   android:id="@+id/container"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   tools:context=".MainActivity"/>

這裡顯示的是一個簡單的 <FrameLayout>,可做為活動顯示的任何片段的容器。

接著開啟「LoginFragment.kt

LoginFragment.kt

package com.google.codelabs.mdc.kotlin.shrine

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment

class LoginFragment : Fragment() {

   override fun onCreateView(
           inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
       // Inflate the layout for this fragment
       val view = inflater.inflate(R.layout.shr_login_fragment, container, false)

       return view
   }
}

LoginFragment 會加載 shr_login_fragment 版面配置檔案,並在 onCreateView() 中顯示。

接著,我們來看看 shr_login_fragment.xml 版面配置檔案,瞭解登入頁面的樣貌。

shr_login_fragment.xml

<?xml version="1.0" encoding="utf-8"?>
<ScrollView 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:background="@color/loginPageBackgroundColor"
   tools:context=".LoginFragment">

   <LinearLayout
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:clipChildren="false"
       android:clipToPadding="false"
       android:orientation="vertical"
       android:padding="24dp"
       android:paddingTop="16dp">

       <ImageView
           android:layout_width="64dp"
           android:layout_height="64dp"
           android:layout_gravity="center_horizontal"
           android:layout_marginTop="48dp"
           android:layout_marginBottom="16dp"
           app:srcCompat="@drawable/shr_logo" />

       <TextView
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:layout_gravity="center_horizontal"
           android:layout_marginBottom="132dp"
           android:text="@string/shr_app_name"
           android:textAllCaps="true"
           android:textSize="16sp" />
   </LinearLayout>
</ScrollView>

這裡顯示的 <LinearLayout> 頂端有 <ImageView>,代表神社標誌。

接著,標誌下方有 <TextView> 標記,代表 Shrine 標籤。這個標籤的文字是名為 @string/shr_app_name字串資源。如果您透過 Command + 按一下 (或 Control + 按一下) 字串資源名稱,或是開啟 app -> res -> values -> strings.xml,就會看到已定義字串資源的 strings.xml 檔案。日後加入更多字串資源時,將會在這裡定義這些資源。這個檔案中的每個資源都應有 shr_ 前置字串,表示這些資源屬於 Shrine 應用程式的一部分。

您現在已經熟悉範例程式碼,接下來讓我們實作第一個元件。

3. 新增文字欄位

首先,我們會在登入頁面新增兩個文字欄位,讓使用者輸入使用者名稱和密碼。我們會使用 MDC Text Field 元件,其中內建的功能可顯示浮動標籤和錯誤訊息。

d83c47fb4aed3a82.png

新增 XML

shr_login_fragment.xml 中,在「SHRINE」標籤 <TextView> 下方的 <LinearLayout> 中新增兩個 TextInputLayout 元素,其中包含子項 TextInputEditText

shr_login_fragment.xml

<com.google.android.material.textfield.TextInputLayout
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
   android:layout_margin="4dp"
   android:hint="@string/shr_hint_username">

   <com.google.android.material.textfield.TextInputEditText
       android:layout_width="match_parent"
       android:layout_height="wrap_content" />
</com.google.android.material.textfield.TextInputLayout>

<com.google.android.material.textfield.TextInputLayout
   android:id="@+id/password_text_input"
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
   android:layout_margin="4dp"
   android:hint="@string/shr_hint_password">

   <com.google.android.material.textfield.TextInputEditText
       android:id="@+id/password_edit_text"
       android:layout_width="match_parent"
       android:layout_height="wrap_content" />
</com.google.android.material.textfield.TextInputLayout>

上述程式碼片段代表兩個文字欄位,每個欄位都包含一個 <TextInputLayout> 元素和一個 <TextInputEditText> 子項。每個文字欄位的提示文字是在 android:hint 屬性中指定。

我們已為文字欄位加入兩項新的字串資源:@string/shr_hint_username@string/shr_hint_password。開啟 strings.xml 即可查看這些字串資源。

strings.xml

<string name="shr_hint_username">Username</string>
<string name="shr_hint_password">Password</string>

新增輸入驗證功能

TextInputLayout 元件提供內建錯誤意見回饋功能。

如要顯示錯誤意見回饋,請對 shr_login_fragment.xml 進行下列變更:

  • 將「密碼」 TextInputLayout 元素的 app:errorEnabled 屬性設為 true。這樣一來,文字欄位下方的錯誤訊息就會多出額外的邊框間距。
  • 將「密碼」 TextInputEditText 元素的 android:inputType 屬性設為「textPassword」。這麼做會隱藏密碼欄位的輸入文字。

經過變更後,shr_login_fragment.xml 中的文字欄位應如下所示:

shr_login_fragment.xml

<com.google.android.material.textfield.TextInputLayout
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
   android:layout_margin="4dp"
   android:hint="@string/shr_hint_username">

   <com.google.android.material.textfield.TextInputEditText
       android:layout_width="match_parent"
       android:layout_height="wrap_content" />
</com.google.android.material.textfield.TextInputLayout>

<com.google.android.material.textfield.TextInputLayout
   android:id="@+id/password_text_input"
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
   android:layout_margin="4dp"
   android:hint="@string/shr_hint_password"
   app:errorEnabled="true">

   <com.google.android.material.textfield.TextInputEditText
       android:id="@+id/password_edit_text"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:inputType="textPassword" />
</com.google.android.material.textfield.TextInputLayout>

接著嘗試執行應用程式。您應該會看到一個頁面,其中包含兩個文字欄位,分別是「使用者名稱」和「密碼」!

請查看浮動標籤動畫:

333184b615aed4f7.gif

4. 新增按鈕

接著,我們會在登入頁面新增兩個按鈕:「取消」和「下一步」。我們會使用 MDC Button 元件,該元件內建經典的 Material Design 墨水波紋效果。

4cb0c218948144b4.png

新增 XML

shr_login_fragment.xml 中,將 <RelativeLayout> 新增至 <LinearLayout>TextInputLayout 元素下方。然後在 <RelativeLayout> 中新增兩個 <MaterialButton> 元素。

產生的 XML 檔案應如下所示:

shr_login_fragment.xml

<RelativeLayout
   android:layout_width="match_parent"
   android:layout_height="wrap_content">

   <com.google.android.material.button.MaterialButton
       android:id="@+id/next_button"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_alignParentEnd="true"
       android:layout_alignParentRight="true"
       android:text="@string/shr_button_next" />

   <com.google.android.material.button.MaterialButton
       android:id="@+id/cancel_button"
       style="@style/Widget.MaterialComponents.Button.TextButton"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_marginEnd="12dp"
       android:layout_marginRight="12dp"
       android:layout_toStartOf="@id/next_button"
       android:layout_toLeftOf="@id/next_button"
       android:text="@string/shr_button_cancel" />

</RelativeLayout>

大功告成!執行應用程式時,輕觸每個按鈕都會顯示墨水漣漪效果。

9dd162d65e4a92a2.gif

5. 前往下一個片段

最後,我們會在 LoginFragment.kt 中新增一些 Kotlin 程式碼,以連接「NEXT」按鈕,以便轉換至其他片段。

讓我們在 onCreateView() 下方的 LoginFragment.kt 中新增私人布林值 isPasswordValid 方法,並使用邏輯判斷密碼是否有效。為了方便本示範,我們只會確保密碼長度至少為 8 個半形字元:

LoginFragment.kt

private fun isPasswordValid(text: Editable?): Boolean {
   return text != null && text.length >= 8
}

接下來,在「Next」按鈕中加入點擊事件監聽器,根據剛剛建立的 isPasswordValid() 方法設定並清除錯誤。在 onCreateView() 中,這個點按事件監聽器應放在 inflater 行和 return view 行之間。

現在讓我們在密碼 TextInputEditText 中新增按鍵事件監聽器,監聽會清除錯誤的重要事件。這個事件監聽器也應使用 isPasswordValid() 檢查密碼是否有效。您可以直接在 onCreateView() 中的點擊事件監聽器下方新增此內容。

您的 onCreateView() 方法現在應如下所示:

LoginFragment.kt

override fun onCreateView(
           inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
       // Inflate the layout for this fragment.
       val view = inflater.inflate(R.layout.shr_login_fragment, container, false)

       // Set an error if the password is less than 8 characters.
       view.next_button.setOnClickListener({
           if (!isPasswordValid(password_edit_text.text!!)) {
               password_text_input.error = getString(R.string.shr_error_password)
           } else {
               // Clear the error.
               password_text_input.error = null
           }
       })

       // Clear the error once more than 8 characters are typed.
       view.password_edit_text.setOnKeyListener({ _, _, _ ->
           if (isPasswordValid(password_edit_text.text!!)) {
               // Clear the error.
               password_text_input.error = null
           }
           false
       })

       return view
   }
}

現在,我們可以前往其他片段。錯誤驗證成功時,在 onCreateView() 中更新 OnClickListener,前往其他片段。您的 clickListener 程式碼現在應如下所示:

LoginFragment.kt

// Set an error if the password is less than 8 characters.
view.next_button.setOnClickListener({
   if (!isPasswordValid(password_edit_text.text!!)) {
       password_text_input.error = getString(R.string.shr_error_password)
   } else {
       // Clear the error.
       password_text_input.error = null
       // Navigate to the next Fragment.
       (activity as NavigationHost).navigateTo(ProductGridFragment(), false)
   }
})

我們在點擊事件監聽器的 else 案件中,新增 (activity as NavigationHost).navigateTo(ProductGridFragment(), false) 這一行。這行程式碼會從 MainActivity 呼叫 navigateTo() 方法,前往新的片段 ProductGridFragment。目前這個空白頁面是在 MDC-102 中操作。

現在,請建構應用程式。請繼續按下「下一步」按鈕。

你成功了!這個畫面將是 MDC-102 中下一個程式碼研究室的起點。

6. 大功告成

利用 Android 程式庫的 Material 元件和約 30 行的 Kotlin 程式碼,您已能建立符合 Material Design 指南的精美登入頁面,而且在所有裝置上都能呈現一致的外觀和行為模式。

後續步驟

文字欄位和按鈕是 MDC Android 程式庫中的兩個核心元件,但還有更多其他功能!您可以探索 MDC Android 中的其他元件。或者,您也可以參閱 MDC 102:Material Design 結構和版面配置,瞭解頂端應用程式列、資訊卡檢視畫面和格狀版面配置。感謝您試用 Material Components。希望您喜歡這個程式碼研究室!

我能夠在合理的時間和精力下完成本程式碼研究室

非常同意 同意 中立 不同意 非常不同意

我希望日後繼續使用 Material Design 元件

非常同意 同意 無意見 不同意 非常不同意