1. מבוא
רכיבי Material (MDC) עוזרים למפתחים להטמיע את Material Design. MDC נוצרה על ידי צוות של מהנדסים ומעצבי UX ב-Google. היא כוללת עשרות רכיבי ממשק משתמש יפים ופונקציונליים, וזמינה ל-Android, ל-iOS, לאינטרנט ול-Flutter.material.io/develop |
מהם Material Design ו-Material Components ל-Android?
Material Design היא מערכת ליצירת מוצרים דיגיטליים מרשימים ויפים. צוותי המוצר יכולים לממש את פוטנציאל העיצוב הגדול ביותר שלהם על ידי איחוד של סגנון, מיתוג, אינטראקציה ותנועה תחת מערכת עקרונות ורכיבים עקבית.
במקרה של אפליקציות ל-Android, Material Components for Android (MDC Android) מאחדת בין עיצוב והנדסה באמצעות ספרייה של רכיבים ליצירת עקביות באפליקציה. ככל שמערכת Material Design מתפתחת, הרכיבים האלה מתעדכנים כדי להבטיח הטמעה עקבית ומושלמת של פיקסלים ועמידה בתקני פיתוח הקצה הקדמי של Google. MDC זמין גם באינטרנט, ב-iOS וב-Flutter.
ב-Codelab הזה, תבנו דף כניסה באמצעות כמה רכיבים של MDC Android.
מה תפַתחו
ה-Codelab הזה הוא הראשון מתוך 4 שיעורים שבהם נלמד איך ליצור אפליקציה בשם Shrine, אפליקציית מסחר אלקטרוני ל-Android שמוכרת בגדים ומוצרים לבית. במאמר הזה נסביר איך אפשר להתאים אישית רכיבים כדי לשקף מותג או סגנון כלשהו באמצעות MDC Android.
ב-codelab הזה תיצרו דף כניסה לאפליקציית Shrine, שיכלול:
- שני שדות טקסט, אחד להזנת שם משתמש והשני להזנת סיסמה
- שני לחצנים, אחד ל'ביטול' ואחד ל'הבא'
- שם האפליקציה (Shrine)
- תמונה של הלוגו של Shrine

רכיבי MDC Android ב-Codelab הזה
- שדה טקסט
- כפתור
מה תצטרכו
- ידע בסיסי בפיתוח ל-Android
- Android Studio (אם עדיין לא הורדתם אותו, אפשר להוריד אותו כאן)
- אמולטור או מכשיר Android (זמינים דרך Android Studio)
- קוד לדוגמה (ראו השלב הבא)
מה רמת הניסיון שלך בפיתוח אפליקציות ל-Android?
2. הגדרת סביבת הפיתוח
הפעלת Android Studio
כשפותחים את Android Studio, אמור להופיע חלון עם הכותרת 'ברוכים הבאים ל-Android Studio'. עם זאת, אם זו הפעם הראשונה שאתם מפעילים את Android Studio, אתם צריכים לבצע את השלבים של אשף ההגדרה של Android Studio עם ערכי ברירת המחדל. השלב הזה יכול להימשך כמה דקות, כי צריך להוריד ולהתקין את הקבצים הנדרשים. אפשר להשאיר את התהליך הזה ברקע ולעבור לקטע הבא.
הורדת אפליקציית ה-codelab למתחילים
אפליקציה לתחילת הדרך נמצאת בספרייה material-components-android-codelabs-101-starter/kotlin.
...או לשכפל אותו מ-GitHub
כדי לשכפל את ה-codelab הזה מ-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 (ברוכים הבאים ל-Android Studio), לוחצים על Open an existing Android Studio project (פתיחת פרויקט קיים של Android Studio). עוברים לספרייה שבה התקנתם את קוד הדוגמה ובוחרים באפשרות kotlin -> shrine (או מחפשים במחשב את shrine) כדי לפתוח את פרויקט המשלוח.
- מחכים כמה רגעים עד ש-Android Studio יבנה ויסנכרן את הפרויקט, כפי שמצוין על ידי אינדיקטורים של פעילות לאורך החלק התחתון של חלון Android Studio.
- בשלב הזה, יכול להיות ש-Android Studio יציג שגיאות build כי חסר לכם Android SDK או כלי build, כמו השגיאה שמוצגת למטה. פועלים לפי ההוראות ב-Android Studio כדי להתקין או לעדכן את התוספים האלה ולסנכרן את הפרויקט.
הוספת יחסי תלות בפרויקט
הפרויקט צריך להיות תלוי בספריית התמיכה של MDC ב-Android. התלות הזו כבר אמורה להופיע בקוד לדוגמה שהורדתם, אבל מומלץ לבצע את השלבים הבאים כדי לוודא זאת.
- עוברים לקובץ
build.gradleשל המודולappומוודאים שהבלוק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 בקוד לדוגמה שלנו כדי להציג קטעים ולנווט בין קטעים.
פותחים את MainActivity.kt בספרייה shrine -> app -> src -> main -> java -> com.google.codelabs.mdc.kotlin.shrine. היא צריכה לכלול את הפרטים הבאים:
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()
}
}
הפעילות הזו מציגה את קובץ הפריסה R.layout.shr_main_activity, שמוגדר ב-shr_main_activity.xml.
אפשר לראות שבonCreate(), MainActivity.kt מתחילה עסקה של Fragment כדי להציג את LoginFragment. ב-codelab הזה נשנה את LoginFragment. בפעילות מיושמת גם שיטת navigateTo(Fragment), שמוגדרת ב-NavigationHost, שמאפשרת לכל מקטע לעבור למקטע אחר.
מקישים על Command + Click (או על Control + Click) 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 מבצע inflate לקובץ הפריסה 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> בחלק העליון, שמייצג את הלוגו של Shrine.
אחרי הלוגו מופיע התג <TextView> שמייצג את התווית Shrine. הטקסט של התווית הזו הוא משאב מחרוזת בשם @string/shr_app_name. אם לוחצים על Command + Click (או על Control + Click) על שם משאב המחרוזת, או פותחים את app -> res -> values -> strings.xml, אפשר לראות את הקובץ strings.xml שבו מוגדרים משאבי המחרוזת. כשנוסיף בעתיד עוד משאבי מחרוזות, הם יוגדרו כאן. לכל משאב בקובץ הזה צריך להיות הקידומת shr_ כדי לציין שהוא חלק מאפליקציית Shrine.
עכשיו, אחרי שהכרתם את קוד לתחילת הדרך, נטמיע את הרכיב הראשון שלנו.
3. הוספת שדות טקסט
כדי להתחיל, נוסיף שני שדות טקסט לדף הכניסה, שבהם אנשים יוכלו להזין את שם המשתמש והסיסמה שלהם. נשתמש ברכיב MDC Text Field, שכולל פונקציונליות מובנית להצגת תווית צפה והודעות שגיאה.

הוספת ה-XML
ב-shr_login_fragment.xml, מוסיפים שני רכיבי TextInputLayout עם רכיב צאצא TextInputEditText בתוך <LinearLayout>, מתחת לתווית SHRINE <TextView>:
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:
- מגדירים את המאפיין
app:errorEnabledלערךtrueבאלמנט PasswordTextInputLayout. כך תתווסף ריווח פנימי נוסף להודעת השגיאה שמתחת לשדה הטקסט. - במאפיין
android:inputTypeשל רכיב הסיסמהTextInputEditText, מגדירים את הערך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>
עכשיו מנסים להריץ את האפליקציה. אמור להופיע דף עם שני שדות טקסט: Username (שם משתמש) ו-Password (סיסמה).
כדאי לבדוק את האנימציה של התווית הצפה:

4. הוספת כפתורים
בשלב הבא, נוסיף שני לחצנים לדף הכניסה: 'ביטול' ו'הבא'. נשתמש ברכיב MDC Button, שכולל את אפקט האדווה האייקוני של Material Design.

הוספת ה-XML
ב-shr_login_fragment.xml, מוסיפים <RelativeLayout> ל-<LinearLayout>, מתחת לרכיבי TextInputLayout. לאחר מכן מוסיפים שני רכיבי <MaterialButton> לרכיב <RelativeLayout>.
קובץ ה-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. ניווט אל Fragment הבא
לבסוף, נוסיף קוד Kotlin ל-LoginFragment.kt כדי לקשר את הלחצן 'הבא' למעבר למקטע (fragment) אחר.
נוסיף שיטה בוליאנית פרטית isPasswordValid ב-LoginFragment.kt מתחת ל-onCreateView(), עם לוגיקה לקביעה אם הסיסמה תקפה או לא. לצורך ההדגמה הזו, נדאג שהסיסמה תהיה באורך של 8 תווים לפחות:
LoginFragment.kt
private fun isPasswordValid(text: Editable?): Boolean {
return text != null && text.length >= 8
}
לאחר מכן, מוסיפים מאזין ללחיצות ללחצן 'הבא' שמגדיר ומנקה את השגיאה על סמך השיטה isPasswordValid() שיצרנו. ב-onCreateView(), צריך למקם את מאזין הקליקים הזה בין שורת ה-inflater לבין השורה return view.
עכשיו נוסיף פונקציית event listener לסיסמה TextInputEditText כדי להאזין לאירועים של מקשים שיגרמו לניקוי השגיאה. המאזין הזה צריך גם להשתמש ב-isPasswordValid() כדי לבדוק אם הסיסמה תקפה או לא. אפשר להוסיף את הקוד הזה ישירות מתחת ל-click listener ב-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
}
}
עכשיו אפשר לעבור אל מקטע (fragment) אחר. ב-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)
}
})
הוספנו את השורה (activity as NavigationHost).navigateTo(ProductGridFragment(), false) לתרחיש else של ה-listener לקליקים. בשורה הזו מופעלת השיטה navigateTo() מ-MainActivity כדי לעבור אל fragment חדש – ProductGridFragment. כרגע זה דף ריק שעליו תעבדו ב-MDC-102.
עכשיו בונים את האפליקציה. לוחצים על הלחצן Next (הבא).
כל הכבוד! המסך הזה יהיה נקודת ההתחלה של ה-codelab הבא שבו תעבדו ב-MDC-102.
6. הפעולה הושלמה
באמצעות תגי עיצוב בסיסיים של XML וכ-30 שורות של Kotlin, ספריית Material Components for Android עזרה לכם ליצור דף כניסה יפה שעומד בהנחיות של Material Design, וגם נראה ומתנהג באופן עקבי בכל המכשירים.
השלבים הבאים
שדה הטקסט והלחצן הם שני רכיבי ליבה בספריית MDC Android, אבל יש עוד הרבה רכיבים! אפשר לעיין בשאר הרכיבים ב-MDC Android. אפשר גם לעבור אל MDC 102: Material Design Structure and Layout כדי לקבל מידע על סרגל האפליקציה העליון, תצוגת כרטיסי מיקום ופריסת הרשת. תודה שניסית את רכיבי Material. אנחנו מקווים שנהניתם מה-Codelab הזה!