1. 簡介
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 標誌的圖片
本程式碼研究室中的 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 中載入範例程式碼
- 設定精靈完成後,系統會顯示「Welcome to Android Studio」視窗,請按一下「Open an existing Android Studio project」。前往您安裝程式碼範例的目錄,然後選取 kotlin -> Shrine (或在電腦上搜尋 shrine),即可開啟運送專案。
- 請稍候,讓 Android Studio 建構及同步處理專案,Android Studio 視窗底部的活動指標會顯示這項作業的進度。
- 此時,Android Studio 可能會引發部分建構錯誤,因為缺少 Android SDK 或建構工具 (如下所示)。請按照 Android Studio 中的操作說明安裝/更新這些項目,並同步處理專案。
新增專案依附元件
專案需要依附 MDC Android 支援程式庫。您下載的程式碼範例中應該已經包含這個依附元件,但建議您執行下列步驟確認。
- 前往
app
模組的build.gradle
檔案,確認dependencies
區塊包含 MDC Android 的依附元件:
api 'com.google.android.material:material:1.1.0-alpha06'
- (選用) 視需要編輯
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' }
執行範例應用程式
|
大功告成!Shrine 登入頁面的範例程式碼應會在模擬器中執行。你應該會看到「Shrine」名稱,以及下方的 Shrine 標誌。
讓我們來看看程式碼。我們在程式碼範例中提供簡易的 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 元件,其中內建的功能可顯示浮動標籤和錯誤訊息。
新增 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>
接著嘗試執行應用程式。您應該會看到一個頁面,其中包含兩個文字欄位,分別是「使用者名稱」和「密碼」!
請查看浮動標籤動畫:
4. 新增按鈕
接著,我們會在登入頁面新增兩個按鈕:「取消」和「下一步」。我們會使用 MDC Button 元件,該元件內建經典的 Material Design 墨水波紋效果。
新增 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>
大功告成!執行應用程式時,輕觸每個按鈕都會顯示墨水漣漪效果。
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。希望您喜歡這個程式碼研究室!