MDC-102 Android: מבנה ופריסה של חומר (Kotlin)

לוגו_components_color_2x_web_96dp.png

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

material.io/develop

ב-codelab MDC-101, השתמשתם בשני רכיבי Material (MDC) כדי ליצור דף התחברות: שדות טקסט ולחצנים עם דיו לדיו. עכשיו נרחיב את הבסיס על ידי הוספת ניווט, מבנה ונתונים.

מה תיצור

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

  • סרגל אפליקציות מוביל
  • רשימת רשתות מלאה במוצרים

רכיבי MDC-Android ב-codelab זה

  • פריסת AppBarפריסת
  • MaterialCardView

מה צריך?

  • ידע בסיסי בפיתוח Android
  • Android Studio (להורדה כאן אם היא עוד לא מותקנת)
  • אמולטור של Android או מכשיר (זמין ב-Android Studio)
  • הקוד לדוגמה (ראו את השלב הבא)

איזה דירוג מגיע לדעתך לרמת הניסיון שלך בבניית אפליקציות ל-Android?

מתחילים מתחילים בקיאים

ממשיכים מ-MDC-101?

אם השלמתם את MDC-101, הקוד שלכם צריך להיות מוכן למעבדה זו. דלגו לשלב 3: מוסיפים סרגל אפליקציות עליון.

מתחילים מאפס?

להורדת האפליקציה Codelab למתחילים

להורדת האפליקציה למתחילים

האפליקציה למתחילים נמצאת בספרייה של material-components-android-codelabs-102-starter/kotlin. לפני שמתחילים, חשוב לוודא שספרייה אחת (cd) במאגר.

...או לשכפל אותו מ-GitHub

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

git clone https://github.com/material-components/material-components-android-codelabs
cd material-components-android-codelabs/
git checkout 102-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 בונה את האפליקציה, פורס אותה ופותחים אותה באופן אוטומטי במכשיר היעד.

הצלחת! אתם אמורים לראות את דף ההתחברות אל Shrine ממעבדת הקוד של MDC-101.

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

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

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

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

הוספת ווידג'ט של AppBar

ב-shr_product_grid_fragment.xml, מוחקים את הבלוק <LinearLayout> שמכיל את ה-"ביצעת!" TextView והחלפתו בפריטים הבאים:

shr_product_grid_snippet.xml

<com.google.android.material.appbar.AppBarLayout
   android:layout_width="match_parent"
   android:layout_height="wrap_content">

   <androidx.appcompat.widget.Toolbar
       android:id="@+id/app_bar"
       style="@style/Widget.Shrine.Toolbar"
       android:layout_width="match_parent"
       android:layout_height="?attr/actionBarSize"
       app:title="@string/shr_app_name" />
</com.google.android.material.appbar.AppBarLayout>

עכשיו shr_product_grid_fragment.xml אמור להיראות כך:

shr_product_grid_snippet.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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"
   tools:context=".ProductGridFragment">

   <com.google.android.material.appbar.AppBarLayout
       android:layout_width="match_parent"
       android:layout_height="wrap_content">

       <androidx.appcompat.widget.Toolbar
           android:id="@+id/app_bar"
           style="@style/Widget.Shrine.Toolbar"
           android:layout_width="match_parent"
           android:layout_height="?attr/actionBarSize"
           app:title="@string/shr_app_name" />
   </com.google.android.material.appbar.AppBarLayout>
  
</FrameLayout>

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

הוספת סמל ניווט

כאשר אתם עדיין נמצאים בshr_product_grid_fragment.xml, הוסיפו את הרכיבים הבאים לרכיב ה-XML Toolbar שהוספתם הרגע

shr_product_grid_snippet.xml

app:navigationIcon="@drawable/shr_menu"

shr_product_grid_fragment.xml אמור להיראות כך:

shr_product_grid_snippet.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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"
   tools:context=".ProductGridFragment">
  
   <com.google.android.material.appbar.AppBarLayout
       android:layout_width="match_parent"
       android:layout_height="wrap_content">

       <androidx.appcompat.widget.Toolbar
           android:id="@+id/app_bar"
           style="@style/Widget.Shrine.Toolbar"
           android:layout_width="match_parent"
           android:layout_height="?attr/actionBarSize"
           app:navigationIcon="@drawable/shr_menu"
           app:title="@string/shr_app_name" />
   </com.google.android.material.appbar.AppBarLayout>
  
</FrameLayout>

הוספת לחצני פעולות וסגנון של סרגל האפליקציות העליון

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

בפונקציה onCreateView של ProductGridFragment.kt' יש להגדיר את Toolbaractivity כך שישמש כ-ActionBar באמצעות setSupportActionBar. ניתן לעשות זאת לאחר יצירת התצוגה עם inflater.

ProductGridFragment.kt

override fun onCreateView(
       inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
   // Inflate the layout for this fragment with the ProductGrid theme
   val view = inflater.inflate(R.layout.shr_product_grid_fragment, container, false)

   // Set up the toolbar.
   (activity as AppCompatActivity).setSupportActionBar(view.app_bar)

   return view;
}

עכשיו, מתחת לשיטה ששינינו עכשיו כדי להגדיר את סרגל הכלים, נבטל את onCreateOptionsMenu כדי להגדיל את התוכן של shr_toolbar_menu.xml בסרגל הכלים:

ProductGridFragment.kt

override fun onCreateOptionsMenu(menu: Menu, menuInflater: MenuInflater) {
   menuInflater.inflate(R.menu.shr_toolbar_menu, menu)
   super.onCreateOptionsMenu(menu, menuInflater)
}

לבסוף, ניתן לבטל את onCreate() ב-ProductGridFragment.kt. אחרי השיחה אל super(), אפשר להתקשר למספר setHasOptionMenu עם true:

ProductGridFragment.kt

override fun onCreate(savedInstanceState: Bundle?) {
   super.onCreate(savedInstanceState)
   setHasOptionsMenu(true)
}

קטעי הקוד שלמעלה הגדירו את סרגל האפליקציות מפריסת ה-XML שלנו כסרגל הפעולות של הפעילות הזו. הקריאה החוזרת (callback) onCreateOptionsMenu אומרת לעסק מה להשתמש כתפריט שלנו. במקרה כזה, התפריטים בתפריט R.menu.shr_toolbar_menu יופיעו בסרגל האפליקציות. קובץ התפריט מכיל שני פריטים: "Search" &"Filter"

shr_browser_menu.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:app="http://schemas.android.com/apk/res-auto">
   <item
       android:id="@+id/search"
       android:icon="@drawable/shr_search"
       android:title="@string/shr_search_title"
       app:showAsAction="always" />
   <item
       android:id="@+id/filter"
       android:icon="@drawable/shr_filter"
       android:title="@string/shr_filter_title"
       app:showAsAction="always" />
</menu>

לאחר ביצוע השינויים, קובץ ה-ProductGridFragment.kt שלך אמור להיראות כך:

ProductGridFragment.kt

package com.google.codelabs.mdc.kotlin.shrine

import android.os.Bundle
import android.view.LayoutInflater
import android.view.Menu
import android.view.MenuInflater
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.GridLayoutManager
import com.google.codelabs.mdc.kotlin.shrine.network.ProductEntry
import kotlinx.android.synthetic.main.shr_product_grid_fragment.view.*

class ProductGridFragment : Fragment() {

   override fun onCreate(savedInstanceState: Bundle?) {
       super.onCreate(savedInstanceState)
       setHasOptionsMenu(true)
   }

   override fun onCreateView(
           inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
       // Inflate the layout for this fragment with the ProductGrid theme
       val view = inflater.inflate(R.layout.shr_product_grid_fragment, container, false)

       // Set up the tool bar
       (activity as AppCompatActivity).setSupportActionBar(view.app_bar)

       return view;
   }

   override fun onCreateOptionsMenu(menu: Menu, menuInflater: MenuInflater) {
       menuInflater.inflate(R.menu.shr_toolbar_menu, menu)
       super.onCreateOptionsMenu(menu, menuInflater)
   }
}

בונים ומפעילים. מסך הבית אמור להיראות כך:

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

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

הוספת כרטיס

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

shr_product_grid_snippet.xml

<com.google.android.material.card.MaterialCardView
   android:layout_width="160dp"
   android:layout_height="180dp"
   android:layout_marginBottom="16dp"
   android:layout_marginLeft="16dp"
   android:layout_marginRight="16dp"
   android:layout_marginTop="70dp"
   app:cardBackgroundColor="?attr/colorPrimaryDark"
   app:cardCornerRadius="4dp">

   <LinearLayout
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:layout_gravity="bottom"
       android:background="#FFFFFF"
       android:orientation="vertical"
       android:padding="8dp">

       <TextView
           android:layout_width="match_parent"
           android:layout_height="wrap_content"
           android:padding="2dp"
           android:text="@string/shr_product_title"
           android:textAppearance="?attr/textAppearanceHeadline6" />

       <TextView
           android:layout_width="match_parent"
           android:layout_height="wrap_content"
           android:padding="2dp"
           android:text="@string/shr_product_description"
           android:textAppearance="?attr/textAppearanceBody2" />
   </LinearLayout>
</com.google.android.material.card.MaterialCardView>

בנייה והפעלה:

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

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

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

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

הגדרת רשת הכרטיסים

כדאי לבדוק את קובץ ה-shr_product_card.xml שמסרנו לך:

shr_product_card.xml

<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:app="http://schemas.android.com/apk/res-auto"
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
   app:cardBackgroundColor="@android:color/white"
   app:cardElevation="2dp"
   app:cardPreventCornerOverlap="true">

   <LinearLayout
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:orientation="vertical">

       <com.android.volley.toolbox.NetworkImageView
           android:id="@+id/product_image"
           android:layout_width="match_parent"
           android:layout_height="@dimen/shr_product_card_image_height"
           android:background="?attr/colorPrimaryDark"
           android:scaleType="centerCrop" />

       <LinearLayout
           android:layout_width="match_parent"
           android:layout_height="wrap_content"
           android:orientation="vertical"
           android:padding="16dp">

           <TextView
               android:id="@+id/product_title"
               android:layout_width="match_parent"
               android:layout_height="wrap_content"
               android:text="@string/shr_product_title"
               android:textAppearance="?attr/textAppearanceHeadline6" />

           <TextView
               android:id="@+id/product_price"
               android:layout_width="match_parent"
               android:layout_height="wrap_content"
               android:text="@string/shr_product_description"
               android:textAppearance="?attr/textAppearanceBody2" />
       </LinearLayout>
   </LinearLayout>
</com.google.android.material.card.MaterialCardView>

פריסת הכרטיס מכילה כרטיס עם תמונה (במקרה הזה, NetworkImageView, שמאפשר לנו לטעון ולהציג תמונות מכתובת URL) ושתי תמונות TextViews.

בשלב הבא, יש לעיין בProductCardRecyclerViewAdapter שסופק לך. החבילה כלולה בחבילה של ProductGridFragment.

ProductCardRecyclerViewAdapter.kt

package com.google.codelabs.mdc.kotlin.shrine

import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView

import com.google.codelabs.mdc.kotlin.shrine.network.ProductEntry

/**
* Adapter used to show a simple grid of products.
*/
class ProductCardRecyclerViewAdapter(private val productList: List<ProductEntry>) : RecyclerView.Adapter<ProductCardViewHolder>() {

   override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ProductCardViewHolder {
       val layoutView = LayoutInflater.from(parent.context).inflate(R.layout.shr_product_card, parent, false)
       return ProductCardViewHolder(layoutView)
   }

   override fun onBindViewHolder(holder: ProductCardViewHolder, position: Int) {
       // TODO: Put ViewHolder binding code here in MDC-102
   }

   override fun getItemCount(): Int {
       return productList.size
   }
}

כיתת המתאם מנהלת את תוכן הרשת שלנו. כדי לקבוע מה לעשות עם כל תצוגה עם התוכן הנתון, בקרוב נכתוב את הקוד עבור onBindViewHolder().

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

ProductCardViewHolder.kt

package com.google.codelabs.mdc.kotlin.shrine

import android.view.View
import androidx.recyclerview.widget.RecyclerView

class ProductCardViewHolder(itemView: View) //TODO: Find and store views from itemView
   : RecyclerView.ViewHolder(itemView)

כדי להגדיר את הרשת שלנו, קודם אנחנו רוצים להסיר את ה-placeholder MaterialCardView מ-shr_product_grid_fragment.xml. בשלב הבא, צריך להוסיף את הרכיב שמייצג את רשת הכרטיסים שלנו. במקרה כזה, נשתמש ב-RecyclerView. מוסיפים את רכיב RecyclerView ל-shr_product_grid_fragment.xml מתחת לרכיב ה-XML מסוג AppBarLayout:

shr_product_grid_snippet.xml

<androidx.core.widget.NestedScrollView
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:layout_marginTop="56dp"
   android:background="@color/productGridBackgroundColor"
   android:paddingStart="@dimen/shr_product_grid_spacing"
   android:paddingEnd="@dimen/shr_product_grid_spacing"
   app:layout_behavior="@string/appbar_scrolling_view_behavior">

   <androidx.recyclerview.widget.RecyclerView
       android:id="@+id/recycler_view"
       android:layout_width="match_parent"
       android:layout_height="match_parent" />

</androidx.core.widget.NestedScrollView>

shr_product_grid_fragment.xml אמור להיראות כך:

shr_product_grid_snippet.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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"
   tools:context=".ProductGridFragment">

   <com.google.android.material.appbar.AppBarLayout
       android:layout_width="match_parent"
       android:layout_height="wrap_content">

       <androidx.appcompat.widget.Toolbar
           android:id="@+id/app_bar"
           style="@style/Widget.Shrine.Toolbar"
           android:layout_width="match_parent"
           android:layout_height="?attr/actionBarSize"
           app:navigationIcon="@drawable/shr_menu"
           app:title="@string/shr_app_name" />
   </com.google.android.material.appbar.AppBarLayout>

   <androidx.core.widget.NestedScrollView
       android:layout_width="match_parent"
       android:layout_height="match_parent"
       android:layout_marginTop="56dp"
       android:background="@color/productGridBackgroundColor"
       android:paddingStart="@dimen/shr_product_grid_spacing"
       android:paddingEnd="@dimen/shr_product_grid_spacing"
       app:layout_behavior="@string/appbar_scrolling_view_behavior">

       <androidx.recyclerview.widget.RecyclerView
           android:id="@+id/recycler_view"
           android:layout_width="match_parent"
           android:layout_height="match_parent" />

   </androidx.core.widget.NestedScrollView>

</FrameLayout>

לבסוף, בonCreateView(), צריך להוסיף את קוד האתחול של RecyclerView ל-ProductGridFragment.kt אחרי שמתקשרים אל setUpToolbar(view) ולפני ההצהרה return:

ProductGridFragment.kt

override fun onCreateView(
       inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
   // Inflate the layout for this fragment with the ProductGrid theme
   val view = inflater.inflate(R.layout.shr_product_grid_fragment, container, false)

   // Set up the toolbar.
   (activity as AppCompatActivity).setSupportActionBar(view.app_bar)

   // Set up the RecyclerView
   view.recycler_view.setHasFixedSize(true)
   view.recycler_view.layoutManager = GridLayoutManager(context, 2, RecyclerView.VERTICAL, false)
   val adapter = ProductCardRecyclerViewAdapter(
           ProductEntry.initProductEntryList(resources))
   view.recycler_view.adapter = adapter
   val largePadding = resources.getDimensionPixelSize(R.dimen.shr_product_grid_spacing)
   val smallPadding = resources.getDimensionPixelSize(R.dimen.shr_product_grid_spacing_small)
   view.recycler_view.addItemDecoration(ProductGridItemDecoration(largePadding, smallPadding))

   return view;
}

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

עכשיו קובץ ה-ProductGridFragment.kt שלכם אמור להיראות כך:

ProductNetworkFragment.kt

package com.google.codelabs.mdc.kotlin.shrine

import android.os.Bundle
import android.view.LayoutInflater
import android.view.Menu
import android.view.MenuInflater
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.google.codelabs.mdc.kotlin.shrine.network.ProductEntry
import kotlinx.android.synthetic.main.shr_product_grid_fragment.view.*

class ProductGridFragment : Fragment() {

   override fun onCreate(savedInstanceState: Bundle?) {
       super.onCreate(savedInstanceState)
       setHasOptionsMenu(true)
   }

   override fun onCreateView(
           inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
       // Inflate the layout for this fragment with the ProductGrid theme
       val view = inflater.inflate(R.layout.shr_product_grid_fragment, container, false)

       // Set up the toolbar.
       (activity as AppCompatActivity).setSupportActionBar(view.app_bar)

       // Set up the RecyclerView
       view.recycler_view.setHasFixedSize(true)
       view.recycler_view.layoutManager = GridLayoutManager(context, 2, RecyclerView.VERTICAL, false)
       val adapter = ProductCardRecyclerViewAdapter(
               ProductEntry.initProductEntryList(resources))
       view.recycler_view.adapter = adapter
       val largePadding = resources.getDimensionPixelSize(R.dimen.shr_product_grid_spacing)
       val smallPadding = resources.getDimensionPixelSize(R.dimen.shr_product_grid_spacing_small)
       view.recycler_view.addItemDecoration(ProductGridItemDecoration(largePadding, smallPadding))

       return view;
   }

   override fun onCreateOptionsMenu(menu: Menu, menuInflater: MenuInflater) {
       menuInflater.inflate(R.menu.shr_toolbar_menu, menu)
       super.onCreateOptionsMenu(menu, menuInflater)
   }
}

בנייה והפעלה:

הכרטיסים כבר כאן! הם עדיין לא מציגים דבר, לכן כדאי להוסיף נתוני מוצרים.

הוספת תמונות וטקסט

בכל כרטיס צריך להוסיף תמונה, שם מוצר ומחיר. הקטגוריה שלנו (ViewHolder) כוללת את מספר הצפיות בכל כרטיס. בViewHolder, מוסיפים את שלוש התצוגות הבאות.

ProductCardViewHolder.kt

package com.google.codelabs.mdc.kotlin.shrine

import android.view.View
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView

import com.android.volley.toolbox.NetworkImageView

class ProductCardViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {

   var productImage: NetworkImageView = itemView.findViewById(R.id.product_image)
   var productTitle: TextView = itemView.findViewById(R.id.product_title)
   var productPrice: TextView = itemView.findViewById(R.id.product_price)
}

כדי להגדיר את הכותרת, המחיר ותמונת המוצר לכל תצוגת מוצר, יש לעדכן את השיטה onBindViewHolder() ב-ProductCardRecyclerViewAdapter:

ProductCardRecyclerViewAdapter.kt

override fun onBindViewHolder(holder: ProductCardViewHolder, position: Int) {
   if (position < productList.size) {
       val product = productList[position]
       holder.productTitle.text = product.title
       holder.productPrice.text = product.price
       ImageRequester.setImageFromUrl(holder.productImage, product.url)
   }
}

הקוד שמופיע למעלה אומר למתאם של RecyclerView&#39 מה לעשות עם כל כרטיס, באמצעות ViewHolder.

כאן היא מגדירה את נתוני הטקסט בכל אחד מ ViewHolder's TextView , ומפעילה ImageRequester כדי לקבל תמונה מכתובת אתר. ה-ImageRequester היא כיתה שאנחנו מציעים לנוחותך, והיא משתמשת בספרייה של Volley (הנושא הזה מחוץ להיקף של קוד ה-Lab הזה, אבל כדאי לבדוק את הקוד בעצמך).

בנייה והפעלה:

המוצרים שלנו מופיעים עכשיו באפליקציה!

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

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

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

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

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

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

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

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