MDC-101 Android: יסודות החומר (MDC) - יסודות (Kotlin)

1. מבוא

logo_components_color_2x_web_96dp.png

Material Components (MDC) עוזר למפתחים להטמיע Material Design. MDC נוצר על ידי צוות של מהנדסים ומעצבי חוויית המשתמש ב-Google, שכולל עשרות רכיבים יפים ופונקציונליים של ממשק המשתמש. זמין ל-Android, ל-iOS, לאינטרנט ול-Flutter.material.io/develop

מהם Material Design ו-Material Components ל-Android?

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

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

בקודלאב הזה תלמדו ליצור דף כניסה באמצעות כמה מרכיבי MDC Android.

מה תפַתחו

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

ב-Codelab הזה בונים דף התחברות למקדש שמכיל:

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

4cb0c218948144b4.png

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

כדי להעתיק (clone) את סדנת הקוד הזו מ-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) כדי לפתוח את פרויקט Shipping.
  2. ממתינים רגע עד שמערכת Android Studio תסיים לבנות ולסנכרן את הפרויקט, כפי שמוצג באינדיקטורים של הפעילות בחלק התחתון של החלון של Android Studio.
  3. בשלב הזה, ייתכן שיוצגו ב-Android Studio חלק משגיאות ה-build כי ה-SDK של Android או כלי ה-build חסרים לכם, כמו זה שמוצג למטה. כדי להתקין או לעדכן אותם ולסנכרן את הפרויקט, פועלים לפי ההוראות ב-Android Studio.

KzoYWC1S7Se7yL8igi1vXF_mbVxAdl2lg5kb7RODrsVpEng0G6U3NK1Qnn0faBBZd2u71yMXioy9tD-7fv3NXvVO4N3EtMMeWDTmqBMMl6egd9R5uXX0T_SKmahbmRor3wZZHX0ByA

הוספת יחסי תלות של פרויקטים

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

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

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

e7ed014e84755811.png

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

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

3. הוספת שדות טקסט

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

d83c47fb4aed3a82.png

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

אחרי ביצוע השינויים האלה, שדות הטקסט ב-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, שמגיע עם אפקט גלי הדיו האיקוני של עיצוב חדשני תלת-ממדי מובנה.

4cb0c218948144b4.png

מוסיפים את ה-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>

זהו! כשמפעילים את האפליקציה, מופיעה גלים של דיו כשמקישים על כל אחד מהלחצנים.

9dd162d65e4a92a2.gif

5. עבור למקטע הבא

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

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

LoginFragment.kt

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

בשלב הבא, מוסיפים האזנה לקליקים ללחצן 'הבא', שמגדיר ומנקה את השגיאה בהתאם ל-method 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)
   }
})

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

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

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

6. הפעולה הושלמה

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

השלבים הבאים

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

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

נכון מאוד נכון אין לי דעה לכאן או לכאן לא נכון לא נכון בכלל

ארצה להמשיך להשתמש ברכיבי Material Materials בעתיד

נכון מאוד נכון ניטרלי לא נכון לא נכון בכלל