רכיבי Material (MDC) עוזרים למפתחים להטמיע את Material Design. MDC נוצר על ידי צוות של מהנדסים ומעצבי UX ב-Google, והוא כולל עשרות רכיבי ממשק משתמש יפים ופונקציונליים. הוא זמין ל-Android, ל-iOS, לאינטרנט ול-Flutter. material.io/develop |
ב-codelab MDC-101, השתמשתם בשני רכיבי Material (MDC) כדי ליצור דף כניסה: שדות טקסט ולחצנים עם אפקט גלי דיו. עכשיו נרחיב את הבסיס הזה ונוסיף ניווט, מבנה ונתונים.
מה תפַתחו
ב-codelab הזה תיצרו מסך בית לאפליקציה בשם Shrine, אפליקציית מסחר אלקטרוני למכירת בגדים ומוצרים לבית. היא תכלול:
- סרגל אפליקציה עליון
- רשימת מוצרים בפריסה של רשת
רכיבי MDC-Android ב-Codelab הזה
- AppBarLayout
- MaterialCardView
מה צריך להכין
- ידע בסיסי בפיתוח ל-Android
- Android Studio (אם עדיין לא הורדתם אותו, אפשר להוריד אותו כאן)
- אמולטור או מכשיר Android (זמינים דרך Android Studio)
- קוד לדוגמה (ראו השלב הבא)
מה רמת הניסיון שלך בפיתוח אפליקציות ל-Android?
המשך מ-MDC-101?
אם השלמתם את MDC-101, הקוד שלכם אמור להיות מוכן ל-codelab הזה. אפשר לדלג לשלב 3: הוספת סרגל אפליקציות עליון.
מתחילים מאפס?
הורדת אפליקציית ה-Codelab לתחילת הדרך
אפליקציית המתחילים נמצאת בספרייה material-components-android-codelabs-102-starter/kotlin
. חשוב לוודא שאתם נמצאים בספרייה cd
לפני שמתחילים.
...או לשכפל אותו מ-GitHub
כדי לשכפל את ה-Codelab הזה מ-GitHub, מריצים את הפקודות הבאות:
git clone https://github.com/material-components/material-components-android-codelabs cd material-components-android-codelabs/ git checkout 102-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 מתוך ה-codelab MDC-101.
עכשיו, אחרי שמסך הכניסה נראה טוב, נמלא את האפליקציה במוצרים.
מסך הבית מוצג כשסוגרים את דף הכניסה, עם הכיתוב 'הצלחת!'. נהדר! אבל עכשיו למשתמש אין פעולות לבצע, או תחושה של מיקום באפליקציה. כדי לפתור את הבעיה הזו, הגיע הזמן להוסיף ניווט.
Material Design מציע דפוסי ניווט שמבטיחים מידה גבוהה של שימושיות. אחד מהרכיבים הבולטים ביותר הוא סרגל האפליקציות העליון.
כדי לספק ניווט ולאפשר למשתמשים גישה מהירה לפעולות אחרות, נוסיף סרגל אפליקציה עליון.
הוספת ווידג'ט של סרגל אפליקציות
ב-shr_product_grid_fragment.xml
, מוחקים את הבלוק <LinearLayout>
שמכיל את הכיתוב 'הצלחת!'. TextView
ומחליפים אותו בטקסט הבא:
shr_product_grid_fragment.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_fragment.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_fragment.xml
app:navigationIcon="@drawable/shr_menu"
התג shr_product_grid_fragment.xml
אמור להיראות כך:
shr_product_grid_fragment.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, הם נקראים לחצני פעולה. אנחנו נסגנן את סרגל האפליקציות העליון ונוסיף לו לחצני פעולה באופן פרוגרמטי.
בפונקציה ProductGridFragment.kt
של onCreateView
, מגדירים את Toolbar
של activity
לשימוש כ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 שלנו כסרגל הפעולות לפעילות הזו. הקריאה החוזרת onCreateOptionsMenu
מציינת לפעילות מה צריך לשמש כתפריט שלנו. במקרה הזה, הפריטים בתפריט מ-R.menu.shr_toolbar_menu
יופיעו בסרגל האפליקציות. קובץ התפריט מכיל שני פריטים: 'חיפוש' ו'סינון'.
shr_toolbar_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)
}
}
מבצעים build והרצה. מסך הבית אמור להיראות כך:
בסרגל הכלים מופיעים עכשיו סמל ניווט, כותרת ושני סמלי פעולה בצד שמאל. בסרגל הכלים מוצגת גם ההגבהה באמצעות צל עדין שמראה שהוא נמצא בשכבה שונה מהתוכן.
עכשיו, כשיש לאפליקציה שלנו מבנה מסוים, נארגן את התוכן ונציב אותו בכרטיסים.
הוספת כרטיס
נתחיל בהוספת כרטיס אחד מתחת לסרגל האפליקציות העליון. בכרטיס צריכים להיות אזור לתמונה, כותרת ותווית לטקסט משני. מוסיפים את הטקסט הבא בקובץ shr_product_grid_fragment.xml
מתחת ל-AppBarLayout
.
shr_product_grid_fragment.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>
גרסת build והפעלה:
בתצוגה המקדימה הזו אפשר לראות שהכרטיס מוזח מהקצה הימני, שיש לו פינות מעוגלות וצל (שמבטא את הגובה של הכרטיס). הרכיב כולו נקרא 'מאגר'. חוץ מהקונטיינר, כל הרכיבים בתוכו הם אופציונליים.
אתם יכולים להוסיף את הרכיבים הבאים למאגר: טקסט של כותרת, תמונה ממוזערת או אווטאר, טקסט של כותרת משנה, קווי הפרדה ואפילו לחצנים וסמלים. לדוגמה, הכרטיס שיצרנו הרגע מכיל שני רכיבי TextView
(אחד לכותרת ואחד לטקסט המשני) בתוך רכיב LinearLayout
, שמוצבים בתחתית הכרטיס.
בדרך כלל הכרטיסים מוצגים באוסף עם כרטיסים אחרים. בקטע הבא של ה-codelab הזה, נציג אותם כאוסף ברשת.
אם יש כמה כרטיסים במסך, הם מקובצים יחד לאוסף אחד או יותר. הקלפים ברשת נמצאים באותו מישור, כלומר הם חולקים את אותו גובה מנוחה (אלא אם הם נאספים או נגררים, אבל לא נסביר על זה ב-codelab הזה).
הגדרת פריסת כרטיסים
כדאי לעיין בקובץ 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
. במחלקת התצוגות הזו מאוחסנות התצוגות שמשפיעות על פריסת הכרטיסים שלנו, כדי שנוכל לשנות אותן מאוחר יותר.
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
מתחת לרכיב AppBarLayout
XML:
shr_product_grid_fragment.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_fragment.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
.
קובץ 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 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)
}
}
גרסת build והפעלה:
הכרטיסים מופיעים עכשיו! הן עדיין לא מציגות כלום, אז בואו נוסיף נתוני מוצרים.
הוספת תמונות וטקסט
לכל כרטיס מוסיפים תמונה, שם מוצר ומחיר. ההפשטה 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()
method ב-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
מה לעשות עם כל כרטיס, באמצעות ViewHolder
.
בדוגמה הזו, המערכת מגדירה את נתוני הטקסט בכל אחד מהרכיבים ViewHolder
's TextView
s, וקוראת ל-ImageRequester
כדי לקבל תמונה מכתובת URL. ImageRequester
היא מחלקה שסיפקנו לנוחיותכם, והיא משתמשת בספריית Volley
(זה נושא שלא נכלל בהיקף של ה-codelab הזה, אבל אתם מוזמנים לעיין בקוד בעצמכם).
גרסת build והפעלה:
המוצרים שלנו מופיעים עכשיו באפליקציה.
באפליקציה שלנו יש תהליך בסיסי שמעביר את המשתמש ממסך הכניסה למסך הבית, שבו אפשר לראות את המוצרים. בכמה שורות קוד בלבד, הוספנו סרגל אפליקציות עליון עם כותרת ושלושה לחצנים, ורשת של כרטיסים להצגת התוכן של האפליקציה. מסך הבית שלנו פשוט ופונקציונלי, עם מבנה בסיסי ותוכן שניתן לפעולה.
השלבים הבאים
עם סרגל האפליקציות העליון, הכרטיס, שדה הטקסט והלחצן, השתמשנו עכשיו בארבעה רכיבי ליבה של Material Design מהספרייה MDC-Android. אפשר לעיין בעוד רכיבים בקטלוג של MDC-Android.
האפליקציה שלנו פועלת באופן מלא, אבל עדיין לא משקפת מותג או סגנון מסוימים. ב-MDC-103: Material Design Theming with Color, Shape, Elevation and Type, נתאים אישית את הסגנון של הרכיבים האלה כדי להציג מותג מודרני ודינמי.