1. مقدمة
تساعد المكونات المادية (MDC) المطورين على تنفيذ التصميم المتعدد الأبعاد. يضم مركز MDC، الذي أنشأه فريق من المهندسين ومصممي تجربة المستخدم في Google، عشرات من مكونات واجهة المستخدم الجميلة والعملية، وهو متاح لأجهزة Android وiOS والويب وFlutter.material.io/develop |
في درس تطبيقي عن الترميز MDC-101، استخدمت مكونَين من مكونات المواد (MDC) لإنشاء صفحة تسجيل دخول، وهما الحقول النصية والأزرار التي تحتوي على تموجات الحبر. الآن دعنا نتوسع على هذا الأساس بإضافة التنقل والهيكل والبيانات.
ما الذي ستنشئه
في هذا الدرس التطبيقي حول الترميز، ستنشئ شاشة رئيسية لتطبيق يسمى Shrine، وهو تطبيق للتجارة الإلكترونية يبيع الملابس والسلع المنزلية. سيتضمّن المحتوى ما يلي:
- شريط التطبيق العلوي
- قائمة شبكية مليئة بالمنتجات
مكونات MDC-Android في هذا الدرس التطبيقي حول الترميز
- AppBarLayout
- MaterialCardView
المتطلبات
- معرفة أساسية بتطوير تطبيقات Android
- استوديو Android (يمكنك تنزيله من هنا إذا لم يكن متوفّرًا لديك)
- محاكي أو جهاز Android (متاح من خلال "استوديو Android")
- نموذج الرمز (انظر الخطوة التالية)
ما هو تقييمك لمستوى خبرتك في إنشاء تطبيقات Android؟
2. إعداد بيئة التطوير
هل تريد المتابعة من MDC-101؟
إذا أكملت MDC-101، يجب أن يكون الرمز جاهزًا لهذا الدرس التطبيقي حول الترميز. التخطّي إلى الخطوة 3: إضافة شريط تطبيق علوي
هل تريد البدء من نقطة الصفر؟
تنزيل تطبيق "الدرس التطبيقي حول الترميز" للمبتدئين
يتوفّر تطبيق إجراء التفعيل في دليل 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"
- بعد انتهاء معالج الإعداد وظهور نافذة مرحبًا بك في استوديو Android، انقر على فتح مشروع استوديو Android حالي. انتقل إلى الدليل الذي قمت فيه بتثبيت نموذج التعليمات البرمجية، وحدد kotlin ->. ضريح (أو ابحث عن كلمة ضريح في جهاز الكمبيوتر) لفتح مشروع الشحن.
- انتظِر قليلاً حتى ينشئ "استوديو Android" المشروع ويزامنه، كما هو موضّح من خلال مؤشرات النشاط أسفل نافذة "استوديو Android".
- في هذه المرحلة، قد يعرض "استوديو Android" بعض أخطاء الإصدار بسبب عدم توفُّر حزمة تطوير البرامج (SDK) لنظام التشغيل Android أو أدوات الإصدار، مثل الأداة الموضّحة أدناه. اتّبِع التعليمات الواردة في "استوديو Android" لتثبيت هذه العناصر أو تحديثها ومزامنة مشروعك.
إضافة تبعيات المشروع
يجب أن يعتمد المشروع على مكتبة دعم MDC Android. يُفترض أن يحتوي نموذج التعليمات البرمجية الذي نزّلته بالفعل على هذه التبعية، ولكن من الجيد القيام بالخطوات التالية للتأكد.
- انتقِل إلى ملف
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 من الدرس التطبيقي MDC-101.
الآن بعد أن أصبحت شاشة تسجيل الدخول تبدو جيدة، لنملأ التطبيق ببعض المنتجات.
3- إضافة شريط تطبيق علوي
يتم إظهار الشاشة الرئيسية عند إغلاق صفحة تسجيل الدخول، مع ظهور شاشة تعرض رسالة "لقد فعلتها!". رائع. ولكن الآن ليس لدى المستخدم أي إجراءات يتعين اتخاذها، أو أي معرفة بمكان وجوده في التطبيق. للمساعدة في ذلك، حان الوقت لإضافة التنقّل.
يوفر Material Design أنماط تنقل تضمن درجة عالية من قابلية الاستخدام. أحد المكوّنات الأكثر وضوحًا هو شريط التطبيق العلوي.
لتوفير إمكانية التنقل ومنح المستخدمين إمكانية الوصول السريع إلى إجراءات أخرى، يمكننا إضافة شريط تطبيق علوي.
إضافة تطبيق 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
، اضبط 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)
}
}
البناء والتشغيل. يُفترض أن تظهر شاشتك الرئيسية على النحو التالي:
الآن يحتوي شريط الأدوات على أيقونة تنقل وعنوان ورمزي إجراء على الجانب الأيمن. يعرض شريط الأدوات أيضًا المسقط الرأسي باستخدام ظل خفيف يُظهر أنه على طبقة مختلفة عن المحتوى.
4. إضافة بطاقة
الآن بعد أن أصبح تطبيقنا له بعض الهياكل، دعنا ننظم المحتوى عن طريق وضعه في بطاقات.
إضافة بطاقة
لنبدأ بإضافة بطاقة واحدة أسفل شريط التطبيق العلوي. يجب أن تحتوي البطاقة على منطقة للصورة وعنوان وتصنيف للنص الثانوي. أضف ما يلي في 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>
الإنشاء والتشغيل:
في هذه المعاينة، يمكنك رؤية إدراج البطاقة من الحافة اليسرى، وبها زوايا دائرية وظل (يعبّر عن ارتفاع البطاقة). يُطلق على العنصر بأكمله اسم "الحاوية". بالإضافة إلى الحاوية، تكون جميع العناصر المضمّنة فيها اختيارية.
يمكنك إضافة العناصر التالية إلى حاوية: نص العنوان، والصورة المصغّرة أو الصورة الرمزية، ونص العنوان الفرعي، والفواصل، وحتى الأزرار والرموز. على سبيل المثال، تحتوي البطاقة التي أنشأناها للتو على عنصرَي TextView
(أحدهما للعنوان، والثاني للنص الثانوي) في LinearLayout
، مع المحاذاة إلى أسفل البطاقة.
تظهر البطاقات عادةً في مجموعة مع بطاقات أخرى. في القسم التالي من هذا الدرس التطبيقي حول الترميز، سنضعها كمجموعة ضمن شبكة.
5- إنشاء شبكة بطاقات
عند عرض بطاقات متعددة في شاشة، يتم تجميعها معًا في مجموعة واحدة أو أكثر. إن البطاقات الموجودة في الشبكة متماثلة، أي أنها تشترك في نفس المسقط الرأسي مثل بعضها البعض (ما لم يتم التقاطها أو سحبها، لكننا لن نتناول ذلك في هذا الدرس التطبيقي حول الترميز).
إعداد شبكة بطاقات
ألقِ نظرة على ملف 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)
لإعداد الشبكة، نرغب أولاً في إزالة العنصر النائب 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)
}
}
الإنشاء والتشغيل:
البطاقات متوفرة الآن. إنّها لا تعرض أي بيانات حتى الآن، لذا سنضيف بعض بيانات المنتجات.
إضافة صور ونص
أضِف صورةً واسم منتج وسعرًا لكل بطاقة. يحتفظ تجريد 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
ما يجب فعله بكل بطاقة عند استخدام ViewHolder
.
في هذه الحالة، يتم ضبط البيانات النصية على كل قيمة من TextView
للسمة ViewHolder
، وطلب رقم ImageRequester
للحصول على صورة من عنوان URL. إنّ ImageRequester
هو أحد الصفوف التي وفّرناها لتيسير الأمر عليك، وهو يستخدم مكتبة Volley
(هذا موضوع خارج نطاق هذا الدرس التطبيقي حول الترميز، ولكن يمكنك استكشاف الرمز بنفسك).
الإنشاء والتشغيل:
تظهر منتجاتنا الآن في التطبيق.
6- ملخّص
يحتوي تطبيقنا على تدفق أساسي ينقل المستخدم من شاشة تسجيل الدخول إلى الشاشة الرئيسية، حيث يمكن عرض المنتجات. في بضعة أسطر فقط من التعليمات البرمجية، أضفنا شريط تطبيق علوي به عنوان وثلاثة أزرار وشبكة من البطاقات لتقديم محتوى تطبيقنا. وأصبحت شاشتنا الرئيسية الآن بسيطة وعملية، وبها بنية أساسية ومحتوى قابل للتنفيذ.
الخطوات التالية
باستخدام شريط التطبيق العلوي والبطاقة وحقل النص والزر، استخدمنا الآن أربعة مكونات أساسية في Material Design من مكتبة MDC-Android! يمكنك استكشاف المزيد من المكونات من خلال الانتقال إلى كتالوج MDC-Android.
على الرغم من وظائفه الكاملة، لا يعبّر تطبيقنا عن أي علامة تجارية أو نمط معيّن. في MDC-103: تحديد مظهر متعدد الأبعاد حسب اللون والشكل والارتفاع والنوع، سنخصِّص نمط هذه المكوّنات للتعبير عن علامة تجارية عصرية ونابضة بالحياة.