MDC-102 Android: بنية المواد وتنسيقها (Kotlin)

logo_components_color_2x_web_96dp.png

تساعد المكونات المادية (MDC) مطوّري البرامج على تنفيذ التصميم المتعدد الأبعاد. أنشأ فريق من المهندسين ومصمِّمي تجارب المستخدمين في Google العشرات من مكوّنات واجهة المستخدم الجميلة والعملية، وهي متوفّرة لنظامَي التشغيل Android وiOS والويب وFltter.

material.io/develop

في الترميز الدرسي MDC-101، استخدمت اثنين من المكونات المادية (MDC) لإنشاء صفحة تسجيل دخول: حقول نصية وأزرار تتضمن موجات حبر. والآن، سنعمل على توسيع نطاق هذه القاعدة من خلال إضافة عناصر التنقّل والبنية والبيانات.

العناصر التي سيتم إنشاؤها

في هذا الدرس التطبيقي حول الترميز، ستنشئ شاشة رئيسية لتطبيق يُسمى Shrine، وهو تطبيق للتجارة الإلكترونية يبيع الملابس والسلع المنزلية. ستحتوي على:

  • شريط أهم التطبيقات
  • قائمة شبكة مليئة بالمنتجات

مكوّنات MDC-Android في هذا الدرس التطبيقي حول الترميز

  • تنسيق AppBar
  • عرض MaterialCard

المتطلبات اللازمة

  • معرفة أساسية بتطوير تطبيقات Android
  • استوديو Android (يمكنك تنزيله هنا إذا لم يكن لديك حاليًا)
  • محاكي أو جهاز يعمل بنظام التشغيل Android (متاح من خلال "استوديو Android")
  • نموذج الرمز (يُرجى الاطّلاع على الخطوة التالية)

كيف تقيّم مستوى خبرتك في إنشاء التطبيقات المتوافقة مع Android؟

مبتدئ متوسط محترف

هل تريد المتابعة من MDC-101؟

في حال إكمال MDC-101، يجب أن يكون الرمز جاهزًا لهذا الدرس التطبيقي حول الترميز. التخطّي إلى الخطوة 3: إضافة شريط أهم التطبيقات

هل تريد إطلاق الخدمة من جديد؟

تنزيل تطبيق Codelab للمبتدئين

تنزيل تطبيق إجراء التفعيل

يتوفّر تطبيق إجراء التفعيل في الدليل material-components-android-codelabs-102-starter/kotlin. احرص على cd في هذا الدليل قبل البدء.

...أو استنساخه من GitHub

لإنشاء نسخة طبق الأصل من هذا الدرس التطبيقي حول الترميز من GitHub، نفِّذ الأوامر التالية:

git clone https://github.com/material-components/material-components-android-codelabs
cd material-components-android-codelabs/
git checkout 102-starter

تحميل رمز إجراء التفعيل في "استوديو Android"

  1. بعد انتهاء معالج الإعداد وظهور النافذة مرحبًا بك في استوديو Android، انقر على فتح مشروع حالي في Android Studio. انتقِل إلى الدليل الذي ثبَّت فيه الرمز النموذجي، واختَر kotlin ->ضريح (أو ابحث في جهاز الكمبيوتر عن shrine) لفتح مشروع الشحن.
  2. انتظر قليلاً حتى يُنشئ Android Studio المشروع ويزامنه، كما هو موضح من خلال مؤشرات الأنشطة أسفل نافذة Android Studio.
  3. في هذه المرحلة، قد يطرح Android Studio بعض أخطاء الإصدار لأنك تفتقد إلى حزمة تطوير البرامج (SDK) لنظام التشغيل Android أو أدوات الإصدار، مثل الأداة الموضّحة في ما يلي. اتبع التعليمات الواردة في "استوديو Android" لتثبيت هذه التطبيقات أو تعديلها ومزامنة مشروعك.

إضافة تبعيات المشاريع

يحتاج المشروع إلى اعتمادية على مكتبة دعم 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. تأكَّد من أنّ بنية الإصدار على يمين زر التشغيل / التشغيل هي app.
  2. اضغط على الزر تشغيل / تشغيل الأخضر لإنشاء التطبيق وتشغيله.
  3. في نافذة اختيار هدف النشر، إذا كان لديك جهاز Android مُدرَج في الأجهزة المتاحة، يمكنك التخطّي إلى الخطوة 8. بخلاف ذلك، انقر على إنشاء جهاز افتراضي جديد.
  4. في شاشة اختيار الأجهزة، اختَر جهاز هاتف، مثل Pixel 2، ثم انقر على التالي.
  5. في شاشة System System (صورة النظام)، اختَر إصدار Android حديثًا، ويُفضَّل أن يكون أعلى مستوى لواجهة برمجة التطبيقات. وفي حال عدم تثبيت التطبيق، انقر على الرابط تنزيل الذي يظهر، ثم أكمِل عملية التنزيل.
  6. انقر على التالي.
  7. في شاشة جهاز Android الافتراضي (AVD)، اترك الإعدادات كما هي وانقر على إنهاء.
  8. اختَر جهاز Android من مربع حوار الهدف للنشر.
  9. انقر على حسنًا.
  10. ينشئ Android Studio التطبيق وينشره ويفتحه تلقائيًا على الجهاز المستهدف.

نجحت عملية تسجيل الدخول. من المفترض أن تظهر لك صفحة تسجيل الدخول في Shrine من الدرس التطبيقي حول الترميز MDC-101.

الآن وبعد ظهور شاشة تسجيل الدخول بشكل جيد، لنملأ التطبيق ببعض المنتجات.

يتم الكشف عن الشاشة الرئيسية عند إغلاق صفحة تسجيل الدخول، مع شاشة تعرض العبارة "لقد فعلت ذلك!" ذلك أمر رائع! ولكن لا يمكن للمستخدم الآن اتخاذ أي إجراء، أو أي وضع يشير إلى المكان الذي يوجد به في التطبيق. وللمساعدة في ذلك، حان الوقت لإضافة ميزة التنقل.

يوفر التصميم المتعدد الأبعاد أنماط تنقُّل تضمن درجة عالية من سهولة الاستخدام. يُعدّ شريط التطبيقات العلوي من أكثر المكوِّنات ظهورًا.

لتوفير التنقل ومنح المستخدمين إمكانية الوصول السريع إلى الإجراءات الأخرى، دعنا نضيف شريط أهم التطبيقات.

إضافة أداة AppBar

في 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. سيتم تطبيق نمط على شريط التطبيق العلوي وإضافة أزرار الإجراءات إلى قائمته آليًا.

في الدالة onCreateView في ProductGridFragment.kt&#39، يمكنك ضبط activity's Toolbar لاستخدامه كـ ActionBar باستخدام setSupportActionBar. يمكنك إجراء ذلك بعد إنشاء الملف الشخصي باستخدام inflater.

ProductNetworkFragment.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 في شريط الأدوات:

ProductNetworkFragment.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:

ProductNetworkFragment.kt

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

تعمل مقتطفات الرمز أعلاه على ضبط شريط التطبيقات من تنسيق XML ليكون شريط الإجراءات لهذا النشاط. تخبر معاودة الاتصال onCreateOptionsMenu النشاط المطلوب استخدامه كقائمتنا. في هذه الحالة، سيضع عناصر القائمة من R.menu.shr_toolbar_menu في شريط التطبيق. يحتوي ملف القائمة على عنصرين: "Search" &"Filter".

shr_شريط_القائمة.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 على النحو التالي:

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 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_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>

إنشاء وتشغيل:

في هذه المعاينة، يمكنك رؤية البطاقة وهي تقع من الحافة اليسرى وبها زوايا مستديرة وظل (يعبر عن ارتفاع البطاقة). ويُسمى العنصر بالكامل &"container;" وبصرف النظر عن الحاوية، تكون جميع العناصر داخلها اختيارية.

يمكنك إضافة العناصر التالية إلى الحاوية: نص العنوان والصورة المصغّرة أو الصورة الرمزية ونص العنوان الفرعي والتقسيمات وحتى الأزرار والرموز. على سبيل المثال، تحتوي البطاقة التي أنشأناها للتو على TextViews (واحد للعنوان والأخرى للنص الثانوي) في LinearLayout بمحاذاة إلى أسفل البطاقة.

وتظهر البطاقات عادةً في مجموعة تتضمّن بطاقات أخرى. في القسم التالي من هذا الدرس التطبيقي حول الترميز، سنوضّحه كمجموعة في شبكة.

عند ظهور عدة بطاقات في شاشة، يتم تجميعها في مجموعة واحدة أو أكثر. البطاقات في الشبكة هي عبارة عن قيم متماثلة، ما يعني أنها تتشارك نفس مستوى الارتفاع أثناء الراحة (مثل ما لم يتم سحبها أو سحبها، ولكننا لن نغطي ذلك في هذا الدرس التطبيقي حول الترميز).

إعداد شبكة البطاقات

اطّلِع على ملف 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 نفسها.

ProductCardRecyclerViewAdaptiveer.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)

لإعداد الشبكة، سنحتاج أولاً إلى إزالة العنصر النائب 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:

ProductNetworkFragment.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&#39، بالإضافة إلى إعداد محوّل RecyclerView&#39s وإعداده.

من المفترض أن يظهر ملف 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 لضبط العنوان والسعر وصورة كل منتج لكل عرض كما يظهر أدناه:

ProductCardRecyclerViewAdaptiveer.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&#39s الذي يجب فعله بكل بطاقة باستخدام ViewHolder.

في هذه الحالة، يتم إعداد البيانات النصية في كل من TextView وViewHolder، ويتم استدعاء ImageRequester للحصول على صورة من عنوان URL. ImageRequester هي فئة وفّرناها لك، وهي تستخدم مكتبة Volley (وهي موضوع خارج نطاق هذا الدرس التطبيقي حول الترميز، ولكن يمكنك استكشاف الرمز بنفسك).

إنشاء وتشغيل:

تظهر منتجاتنا الآن في التطبيق.

يتضمّن تطبيقنا تدفقًا أساسيًا ينقل المستخدم من شاشة تسجيل الدخول إلى شاشة رئيسية حيث يمكن عرض المنتجات. في بضعة أسطر من الرمز، أضفنا شريط تطبيق علوي يحتوي على عنوان وثلاثة أزرار، ومجموعة من البطاقات لتقديم محتوى التطبيق. أصبحت شاشتنا الرئيسية الآن عملية وبسيطة ذات بنية أساسية ومحتوى قابل للتنفيذ.

الخطوات التالية

باستخدام شريط التطبيق العلوي والبطاقة وحقل النص والزر، بدأنا الآن باستخدام أربعة مكونات أساسية لتصميم المواد الأساسية من مكتبة MDC-Android. يمكنك استكشاف المزيد من المكوّنات من خلال الانتقال إلى كتالوج MDC-Android.

على الرغم من أنّ هذه الميزة تعمل بشكل كامل، إلا أنّها لا تُظهر بعد أي علامة تجارية أو نمط محدّد. في MDC-103: Material Design المظهر باستخدام اللون والشكل والارتفاع والنوع، سنخصص نمط هذه المكونات للتعبير عن علامة تجارية عصرية نابضة بالحياة.

تمكّنتُ من إكمال هذا الدرس التطبيقي بقدرٍ معقول من الوقت والجهد.

أوافق بشدة أوافق محايد أعارض أعارض بشدة

أود مواصلة استخدام المكونات المتعددة في المستقبل

أوافق بشدة أوافق لستُ موافقًا أعارض أعارض بشدة