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 ל-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 הזה בונים דף התחברות למקדש שמכיל:

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

4cb0c218948144b4.png

רכיבי Android של MDC ב-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

  1. כשאשף ההגדרה יסתיים ובחלון ברוכים הבאים אל Android Studio, לוחצים על פתיחת פרויקט קיים של Android Studio. מנווטים לספרייה שבה התקנתם את הקוד לדוגמה ובוחרים באפשרות kotlin -> מקדש (או מחפשים במחשב את המילה מקדש) כדי לפתוח את פרויקט המשלוח.
  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. לוחצים על לחצן ההפעלה / ההפעלה כדי לבנות את האפליקציה ולהפעיל אותה.
  3. בחלון בחירת יעד פריסה, אם כבר יש לכם מכשיר Android שרשום ברשימת המכשירים הזמינים, מדלגים לשלב 8. אחרת, לוחצים על יצירת מכשיר וירטואלי חדש.
  4. במסך בחירת חומרה, בוחרים מכשיר טלפון, כמו Pixel 2, ולוחצים על הבא.
  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, שכולל פונקציונליות מובנית שמציגה תווית צפה והודעות שגיאה.

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. הוספת לחצנים

בשלב הבא, נוסיף שני לחצנים לדף ההתחברות שלנו: "ביטול" ו-"Next". נשתמש ברכיב של לחצן 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
}

בשלב הבא, מוסיפים האזנה לקליקים ל-"Next" (הבא) שמגדיר ומנקה את השגיאה בהתאם לשיטת ה-isPasswordValid() שיצרנו עכשיו. ב-onCreateView(), יש למקם את אוזן הקליקים הזה בין הקו המנפח לבין השורה 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 של המאזינים לקליקים. שורה זו מפעילה את השיטה navigateTo() מ-MainActivity כדי לנווט למקטע חדש – ProductGridFragment. כרגע זהו דף ריק שעליו עליך לעבוד ב-MDC-102.

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

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

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

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

השלבים הבאים

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

הצלחתי להשלים את ה-Codelab הזה תוך השקעה של זמן ומאמץ סבירים

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

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

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