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

לוגו_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/java. לפני שמתחילים, חשוב לוודא שספרייה אחת (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 קיים. עוברים אל הספרייה שבה התקנתם את הקוד לדוגמה ובוחרים באפשרות JavaScript &> מקדש (או מחפשים במחשב את המקדש) כדי לפתוח את פרויקט המקדש.
  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>

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

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

אפשר להוסיף את הרכיב הבא ברכיב Toolbar של shr_product_grid_fragment.xml (שכרגע הוספת לפריסה):

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, הלחצנים האלה נקראים לחצני פעולות.

נעצב את סרגל האפליקציות העליון ונוסיף לו לחצני פעולה באופן פרוגרמטי.

תחילה, ננסה ליצור שיטה להגדרת סרגל הכלים. לשיטה צריכה להיות הפניה לסרגל הכלים באמצעות id שלה, וגם הפניה לפעילות באמצעות getActivity(). אם הפעילות אינה ריקה, Toolbar צריך להגדיר אותה כ-ActionBar באמצעות setSupportActionBar:

ProductGridFragment.JavaScript

private void setUpToolbar(View view) {
   Toolbar toolbar = view.findViewById(R.id.app_bar);
   AppCompatActivity activity = (AppCompatActivity) getActivity();
   if (activity != null) {
       activity.setSupportActionBar(toolbar);
   }
}

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

ProductGridFragment.JavaScript

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater menuInflater) {
   menuInflater.inflate(R.menu.shr_toolbar_menu, menu);
   super.onCreateOptionsMenu(menu, menuInflater);
}

יש להוסיף עכשיו קריאה לשיטה setUpToolbar שהוספנו לתוכן של השיטה onCreateView() באמצעות:

ProductGridFragment.JavaScript

@Override
public View onCreateView(
       @NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
   // Inflate the layout for this fragment with the ProductGrid theme
   View view = inflater.inflate(R.layout.shr_product_grid_fragment, container, false);

   // Set up the toolbar
   setUpToolbar(view);

   return view;
}

לבסוף, יש להוסיף שיטת onCreate() ל-ProductGridFragment.java. בגוף השיטה, יש להגדיר את הפרמטר setHasOptionMenu כ-true.

השיטה אמורה להיראות כך:

ProductGridFragment.JavaScript

@Override
public void onCreate(Bundle savedInstanceState) {
   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.java שלך אמור להיראות כך:

ProductGridFragment.JavaScript

package com.google.codelabs.mdc.java.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 android.widget.Toolbar;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;


public class ProductGridFragment extends Fragment {

   @Override
   public void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setHasOptionsMenu(true);
   }
  
   @Override
   public View onCreateView(
           @NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
       // Inflate the layout for this fragment with the ProductGrid theme
       View view = inflater.inflate(R.layout.shr_product_grid_fragment, container, false);

       // Set up the toolbar
       setUpToolbar(view);

       return view;
   }
  
   private void setUpToolbar(View view) {
       Toolbar toolbar = view.findViewById(R.id.app_bar);
       AppCompatActivity activity = (AppCompatActivity) getActivity();
       if (activity != null) {
           activity.setSupportActionBar(toolbar);
       }
   }

   @Override
   public void 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.JavaScript

package com.google.codelabs.mdc.java.shrine;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import com.google.codelabs.mdc.java.shrine.network.ImageRequester;
import com.google.codelabs.mdc.java.shrine.network.ProductEntry;

import java.util.List;

/**
* Adapter used to show a simple grid of products.
*/
public class ProductCardRecyclerViewAdapter extends RecyclerView.Adapter<ProductCardViewHolder> {

   private List<ProductEntry> productList;
   private ImageRequester imageRequester;

   ProductCardRecyclerViewAdapter(List<ProductEntry> productList) {
       this.productList = productList;
       imageRequester = ImageRequester.getInstance();
   }

   @NonNull
   @Override
   public ProductCardViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
       View layoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.shr_product_card, parent, false);
       return new ProductCardViewHolder(layoutView);
   }

   @Override
   public void onBindViewHolder(@NonNull ProductCardViewHolder holder, int position) {
       // TODO: Put ViewHolder binding code here in MDC-102
   }

   @Override
   public int getItemCount() {
       return productList.size();
   }
}

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

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

ProductCardViewHolder.JavaScript

package com.google.codelabs.mdc.java.shrine;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import android.view.View;

public class ProductCardViewHolder extends RecyclerView.ViewHolder {

   public ProductCardViewHolder(@NonNull View itemView) {
       super(itemView);
       // TODO: Find and store views from itemView
   }
}

כדי להגדיר את הרשת שלנו, קודם אנחנו רוצים להסיר את ה-placeholder MaterialCardView מ-shr_product_grid_fragment.xml. בשלב הבא, צריך להוסיף את הרכיב שמייצג את רשת הכרטיסים שלנו. במקרה הזה, מוסיפים רכיב 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.java אחרי שמתקשרים אל setUpToolbar(view) ולפני ההצהרה return:

ProductGridFragment.JavaScript

@Override
public View onCreateView(
       @NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
   ...
   setUpToolbar(view);

   // Set up the RecyclerView
   RecyclerView recyclerView = view.findViewById(R.id.recycler_view);
   recyclerView.setHasFixedSize(true);
   recyclerView.setLayoutManager(new GridLayoutManager(getContext(), 2, GridLayoutManager.VERTICAL, false));
   ProductCardRecyclerViewAdapter adapter = new ProductCardRecyclerViewAdapter(
           ProductEntry.initProductEntryList(getResources()));
   recyclerView.setAdapter(adapter);
   int largePadding = getResources().getDimensionPixelSize(R.dimen.shr_product_grid_spacing);
   int smallPadding = getResources().getDimensionPixelSize(R.dimen.shr_product_grid_spacing_small);
   recyclerView.addItemDecoration(new ProductGridItemDecoration(largePadding, smallPadding));

   return view;
}

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

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

ProductGridFragment.JavaScript

package com.google.codelabs.mdc.java.shrine;

import android.os.Bundle;
import androidx.recyclerview.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toolbar;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.GridLayoutManager;


import com.google.codelabs.mdc.java.shrine.network.ProductEntry;

public class ProductGridFragment extends Fragment {

   @Override
   public void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setHasOptionsMenu(true);
   }

   @Override
   public View onCreateView(
           @NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
       // Inflate the layout for this fragment with the ProductGrid theme
       View view = inflater.inflate(R.layout.shr_product_grid_fragment, container, false);

       // Set up the toolbar
       setUpToolbar(view);

       // Set up the RecyclerView
       RecyclerView recyclerView = view.findViewById(R.id.recycler_view);
       recyclerView.setHasFixedSize(true);
       recyclerView.setLayoutManager(new GridLayoutManager(getContext(), 2, GridLayoutManager.VERTICAL, false));
       ProductCardRecyclerViewAdapter adapter = new ProductCardRecyclerViewAdapter(
               ProductEntry.initProductEntryList(getResources()));
       recyclerView.setAdapter(adapter);
       int largePadding = getResources().getDimensionPixelSize(R.dimen.shr_product_grid_spacing);
       int smallPadding = getResources().getDimensionPixelSize(R.dimen.shr_product_grid_spacing_small);
       recyclerView.addItemDecoration(new ProductGridItemDecoration(largePadding, smallPadding));

       return view;
   }

   private void setUpToolbar(View view) {
       Toolbar toolbar = view.findViewById(R.id.app_bar);
       AppCompatActivity activity = (AppCompatActivity) getActivity();
       if (activity != null) {
           activity.setSupportActionBar(toolbar);
       }
   }

   @Override
   public void onCreateOptionsMenu(Menu menu, MenuInflater menuInflater) {
       menuInflater.inflate(R.menu.shr_toolbar_menu, menu);
       super.onCreateOptionsMenu(menu, menuInflater);
   }

}

בונים ומפעילים.

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

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

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

ProductCardViewHolder.JavaScript

package com.google.codelabs.mdc.java.shrine;

import androidx.recyclerview.widget.RecyclerView;
import android.view.View;
import android.widget.TextView;
import androidx.annotation.NonNull;

import com.android.volley.toolbox.NetworkImageView;

public class ProductCardViewHolder extends RecyclerView.ViewHolder {

   public NetworkImageView productImage;
   public TextView productTitle;
   public TextView productPrice;

   public ProductCardViewHolder(@NonNull View itemView) {
       super(itemView);
       productImage = itemView.findViewById(R.id.product_image);
       productTitle = itemView.findViewById(R.id.product_title);
       productPrice = itemView.findViewById(R.id.product_price);
   }
}

במתאם של RecyclerView'ViewHolder,, יש לעדכן את השיטה של onBindViewHolder() כדי להגדיר את המידע בכל תצוגה מפורטת:

ProductCardRecyclerViewAdapter.JavaScript

@Override
public void onBindViewHolder(@NonNull ProductCardViewHolder holder, int position) {
   if (productList != null && position < productList.size()) {
       ProductEntry product = productList.get(position);
       holder.productTitle.setText(product.title);
       holder.productPrice.setText(product.price);
       imageRequester.setImageFromUrl(holder.productImage, product.url);
   }
}

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

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

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

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

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

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

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

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

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

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

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

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