רכיבי Material (MDC) עוזרים למפתחים להטמיע את Material Design. MDC נוצר על ידי צוות של מהנדסים ומעצבי UX ב-Google, והוא כולל עשרות רכיבי ממשק משתמש יפים ופונקציונליים. הוא זמין ל-Android, ל-iOS, לאינטרנט ול-Flutter. material.io/develop |
מהם Material Design ורכיבי Material ל-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?
הפעלת 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 support library. התלות הזו אמורה כבר להופיע בקוד לדוגמה שהורדתם, אבל מומלץ לבצע את השלבים הבאים כדי לוודא זאת.
- עוברים לקובץ
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.
אחרי שהכרתם את קוד ההתחלה, בואו ניישם את הרכיב הראשון שלנו.
כדי להתחיל, נוסיף שני שדות טקסט לדף הכניסה, שבהם אנשים יוכלו להזין את שם המשתמש והסיסמה שלהם. נשתמש ברכיב 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 (סיסמה).
כדאי לבדוק את האנימציה של התווית הצפה:
בשלב הבא, נוסיף שני לחצנים לדף הכניסה: 'ביטול' ו'הבא'. נשתמש ברכיב 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>
זהו! כשמפעילים את האפליקציה, מופיע אפקט של דיו כשמקישים על כל כפתור.
לבסוף, נוסיף קוד Kotlin ל-LoginFragment.kt
כדי לקשר את הלחצן 'הבא' למעבר לקטע אחר.
נוסיף שיטה בוליאנית פרטית isPasswordValid
ב-LoginFragment.kt
מתחת ל-onCreateView()
, עם לוגיקה לקביעה אם הסיסמה תקפה או לא. לצורך ההדגמה הזו, נדאג שהסיסמה תהיה באורך של 8 תווים לפחות:
LoginFragment.kt
private fun isPasswordValid(text: Editable?): Boolean {
return text != null && text.length >= 8
}
לאחר מכן, מוסיפים מאזין ללחיצות ללחצן 'הבא' שמגדיר ומנקה את השגיאה על סמך השיטה isPasswordValid()
שיצרנו. ב-onCreateView()
, צריך למקם את מאזין הקליקים הזה בין שורת ה-inflater לבין השורה return view
.
עכשיו נוסיף מאזין למקש לסיסמה 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
}
}
עכשיו אפשר לעבור אל רכיב אחר. ב-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
כדי לעבור אל רכיב חדש – ProductGridFragment
. בשלב הזה הדף ריק, ותעבדו עליו בקורס MDC-102.
עכשיו בונים את האפליקציה. לוחצים על הלחצן 'הבא'.
כל הכבוד! המסך הזה יהיה נקודת ההתחלה של סדנת הקוד הבאה שבה תעבדו ב-MDC-102.
באמצעות תגי עיצוב בסיסיים של XML וכ-30 שורות של Kotlin, ספריית Material Components for Android עזרה לכם ליצור דף כניסה יפה שעומד בהנחיות של Material Design, וגם נראה ומתנהג באופן עקבי בכל המכשירים.
השלבים הבאים
שדה הטקסט והלחצן הם שני רכיבי ליבה בספריית MDC Android, אבל יש עוד הרבה רכיבים אחרים. אפשר לעיין בשאר הרכיבים ב-MDC Android. אפשר גם לעבור אל MDC 102: Material Design Structure and Layout כדי לקבל מידע על סרגל האפליקציות העליון, על תצוגת כרטיסים ועל פריסת רשת. תודה שניסית את רכיבי Material. אנחנו מקווים שנהניתם מה-Codelab הזה.