MDC-101 Android: Material Components (MDC) Basics (Kotlin)

לוגו_components_color_2x_web_96dp.png

רכיבי החומר (MDC) עוזרים למפתחים להטמיע עיצוב חדשני תלת-ממדי. MDC, שנוצר על ידי צוות של מהנדסים ומעצבי חוויית משתמש ב-Google, כולל עשרות רכיבי ממשק משתמש יפים ופונקציונליים, והוא זמין למכשירי Android , iOS, אינטרנט ו-Fluter.

material.io/develop

מהם עיצוב חדשני תלת-ממדי ורכיבי חומר ל-Android?

עיצוב חדשני תלת-ממדי הוא מערכת ליצירת מוצרים דיגיטליים מודגשים ויפים. על ידי איחוד של סגנון, מיתוג, אינטראקציה ותנועה לאורך עקרונות ורכיבים עקביים, צוותי המוצרים יכולים לממש את פוטנציאל העיצוב הגדול ביותר שלהם.

באפליקציות ל-Android, רכיבי הרכיבים ל-Android (MDC ל-Android) מאחדים עיצוב והנדסה עם ספריית רכיבים ליצירת עקביות באפליקציה שלכם. ככל שהמערכת לעיצוב חדשני מתפתחת, הרכיבים האלה מתעדכנים כדי להבטיח הטמעה עקבית בעת שימוש בפיקסלים ולעמוד בתקנים של פיתוח הקצה של Google. MDC זמין גם באינטרנט, ב-iOS וב-Fluter.

במעבדת קוד זו, תצרו דף התחברות באמצעות כמה רכיבים של MDC Android ו-#39.

מה תיצור

Codelab זה הוא הראשון מבין 4 קודי שיעור ה-Lab שיובילו אתכם בבניית אפליקציה בשם Shrine, אפליקציית Android למסחר אלקטרוני שמוכרת בגדים ומוצרים לבית. הוא ידגים איך אפשר להתאים אישית רכיבים כך שישקפו כל מותג או סגנון באמצעות MDC Android.

ב-Codelab הזה, תיצרו דף התחברות לחשבון מקדש שמכיל:

  • שני שדות טקסט, אחד להזנת שם משתמש והשני לסיסמה
  • שני לחצנים, אחד עבור "ביטול" ואחד עבור "הבא"
  • שם האפליקציה (מקדש)
  • תמונת לוגו של המקדש

רכיבי 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

כדי לשכפל את קוד Lab זה מ-GitHub, יש להריץ את הפקודות הבאות:

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

טעינת הקוד למתחילים ב-Android Studio

  1. אחרי שאשף ההגדרה יסתיים והחלון ברוכים הבאים אל Android Studio מוצג, לוחצים על פתיחת פרויקט Android Studio קיים. עוברים אל הספרייה שבה התקנתם את הקוד לדוגמה ובוחרים באפשרות kotlin -> מקדשים (או מחפשים במחשב את השריון) כדי לפתוח את פרויקט המשלוח.
  2. ממתינים רגע עד ש-Android Studio יבנה את הפרויקט ויסנכרן אותו, כפי שמוצג בחלק התחתון של חלון Android Studio.
  3. בשלב זה, Android Studio עשוי להעלות מספר שגיאות build כי חסר לך ה-SDK של Android או כלי פיתוח כמו זה שמוצג בהמשך. יש לפעול לפי ההוראות ב-Android Studio כדי להתקין/לעדכן את הפרויקטים האלה ולסנכרן את הפרויקט.

הוספת תלויות בפרויקט

הפרויקט צריך להיות תלוי בספריית התמיכה של Android ל-MDC. הקוד לדוגמה שהורדת כבר אמור להופיע בתור תלות, אבל מומלץ לבצע את השלבים הבאים כדי לוודא שהוא.

  1. מנווטים לקובץ build.gradle של המודול app ומוודאים שהבלוק 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. יש לוודא שתצורת ה-build שמימין ללחצן 'הפעלה' / הפעלה' היא app.
  2. לוחצים על הלחצן 'הפעלה/הפעלה' הירוק כדי לבנות ולהפעיל את האפליקציה.
  3. בחלון בחר יעד פריסה, אם כבר יש לך מכשיר Android רשום במכשירים הזמינים שלך, דלג לשלב 8. אחרת, לוחצים על יצירת מכשיר וירטואלי חדש.
  4. במסך בחירת חומרה, בוחרים מכשיר טלפון, כמו Pixel 2, ואז לוחצים על הבא.
  5. במסך תמונת מערכת, בוחרים גרסת Android עדכנית, עדיף ברמת ה-API הגבוהה ביותר. אם היא לא מותקנת, לוחצים על הקישור הורדה שמוצג ומשלימים את ההורדה.
  6. לוחצים על Next.
  7. במסך מכשיר וירטואלי של Android (AVD), משאירים את ההגדרות כפי שהן ולוחצים על סיום.
  8. בתיבת הדו-שיח של יעד הפריסה, בוחרים מכשיר Android.
  9. לוחצים על אישור.
  10. Android Studio בונה את האפליקציה, פורס אותה ופותחים אותה באופן אוטומטי במכשיר היעד.

הצלחת! קוד הפתיחה של דף ההתחברות של המקדש צריך לפעול באמולטור שלך. אתם אמורים לראות את השם "מקדש&quot, ואת לוגו המקדש מתחתיו.

בואו נבחן את הקוד. הוספנו קוד ניווט פשוט מסוג Fragment בקוד לדוגמה שלנו כדי להציג מקטעים ולנווט בין חלקים.

יש לפתוח את MainActivity.kt בספרייה shrine -> app -> src -> main -> java -> com.google.codelabs.mdc.kotlin.shrine. עליה להכיל:

PrimaryActivity.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. בשיעור Lab זה, אנחנו נשנה את 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_snippet.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> שמייצג את תווית המקדש מתחת ללוגו. הטקסט של התווית הזו הוא משאב מחרוזת בשם @string/shr_app_name. אם לוחצים על Command + לחיצה (או על Control + לחיצה) על שם משאב המחרוזת, או פותחים את app -> res -> values -> strings.xml, ניתן לראות את הקובץ strings.xml שבו מוגדרים משאבי המחרוזת. כשנוסיף בעתיד משאבי מחרוזת נוספים, הם יוגדרו כאן. כל משאב בקובץ הזה צריך לכלול תחילית shr_ כדי לציין שהם חלק מאפליקציית המקדש.

עכשיו כשאתם מכירים את הקוד למתחילים, כדאי להטמיע את הרכיב הראשון שלנו.

בשלב הראשון, נוסיף שני שדות טקסט לדף ההתחברות שלנו כדי שאנשים יוכלו להזין את שם המשתמש והסיסמה שלהם. נשתמש ברכיב שדה MDC של הטקסט, הכולל פונקציונליות מובנית שמציגה תווית צפה והודעות שגיאה.

הוספת XML

ב-shr_login_fragment.xml, יש להוסיף שני רכיבי TextInputLayout שיש להם צאצא TextInputEditText בתוך <LinearLayout>, מתחת לתווית "SHRINE" בתווית <TextView>:

shr_login_snippet.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 ברכיב סיסמה TextInputLayout. פעולה זו תוסיף רווח של הודעת השגיאה מתחת לשדה הטקסט.
  • יש להגדיר את המאפיין android:inputType כ-"textPassword" ברכיב הסיסמה TextInputEditText. פעולה זו תסתיר את טקסט הקלט בשדה הסיסמה.

בהתאם לשינויים האלה, שדות הטקסט ב-shr_login_fragment.xml אמורים להיראות כך:

shr_login_snippet.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>

עכשיו מנסים להפעיל את האפליקציה. אמור להופיע דף עם שני שדות טקסט עבור "שם משתמש" ו-"סיסמה"!

אנימציה של תווית צפה:

לאחר מכן, נוסיף שני לחצנים לדף ההתחברות שלנו: "Cancel" & "Next." נשתמש ברכיב לחצן MDC, שמגיע עם האפקט המהודר של אפקט הדיו של עיצוב חדשני תלת-ממדי.

הוספת XML

בתוך shr_login_fragment.xml, יש להוסיף <RelativeLayout> אל <LinearLayout>, מתחת לרכיבי TextInputLayout. לאחר מכן מוסיפים ל-<RelativeLayout> שני אלמנטים של <MaterialButton>.

קובץ ה-XML אמור להיראות כך:

shr_login_snippet.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>

זהו! כשתפעילו את האפליקציה, יווצרו דיו של דיו כשתקישו על כל לחצן.

לסיום, נוסיף קוד קוטלין ל-LoginFragment.kt כדי לחבר את הלחצן "Next" ולעבור לחלק אחר.

נוסיף שיטה בוליאנית isPasswordValid ב-LoginFragment.kt מתחת ל-onCreateView(), עם לוגיקה כדי לקבוע אם הסיסמה חוקית או לא. למטרות ההדגמה הזו, נוודא שהסיסמה צריכה להיות באורך 8 תווים לפחות:

LoginFragment.kt

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

בשלב הבא, מוסיפים האזנה לקליק ללחצן "הבא" שמגדיר ומנקה את השגיאה לפי שיטת isPasswordValid() שיצרתם. ב-onCreateView(), יש למקם את ההאזנה הזו לקליק בין הקו המנפח לבין השורה return view.

עכשיו הגיע הזמן להוסיף event listener לסיסמה 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)
   }
})

הוספנו את השורה (activity as NavigationHost).navigateTo(ProductGridFragment(), false) למקרה של else האזנה לקליקים. שורה זו קוראת לשיטה navigateTo() מ-MainActivity כדי לנווט אל שבר חדש – ProductGridFragment. נכון לעכשיו, זהו דף ריק שבו תוכלו לעבוד ב-MDC-102.

עכשיו יש לך אפשרות לבנות את האפליקציה. עליך ללחוץ על הלחצן 'הבא'.

זכית! מסך זה יהיה נקודת ההתחלה של מעבדת הקוד הבאה שלנו שתעבדו עליה ב-MDC-102.

ספריית Material Components ל-Android השתמשה בתגי עיצוב בסיסיים של XML ועם כ-30 שורות של Kotlin עזרה לך ליצור דף כניסה יפה שתואם להנחיות העיצוב של Material, וגם נראה ופועל באופן עקבי בכל המכשירים.

מה אפשר לעשות?

שדה הטקסט והלחצן הם שני רכיבי ליבה בספרייה של MDC ל-Android, אבל יש עוד הרבה רכיבים! תוכלו לחקור את שאר הרכיבים ב-MDC Android. לחלופין, אפשר לעבור אל MDC 102: מבנה ופריסה של עיצוב חדשני תלת-ממדי כדי לקבל מידע על סרגל האפליקציות, תצוגת הכרטיסים ופריסת הרשת המובילים. תודה שניסית את הרכיבים מהותיים. אנחנו מקווים שנהנית ממעבדת הקוד הזו!

הצלחתי להשלים את שיעור הקוד הזה בזמן סביר ובמאמץ מספיק

נכונה מאוד נכונה ניטרלית לא נכונה במידה רבה

אני רוצה להמשיך להשתמש ברכיבי החומר בעתיד

נכונה מאוד נכונה ניטרלית לא נכונה לא נכונה במידה רבה