MergeAdapter هو فئة جديدة تم تقديمها في إعادة التدوير: 1.2.0-alpha02 والتي ستسمح لك بدمج محولات عرض متعددة في RecyclerView واحد. سيسمح لك ذلك بتغليف المنطق لكل خلية في المحول ، وسيسمح لك بإعادة استخدامه في المستقبل.
مشكلة
لنبدأ بمثال. افترض أن لدينا مهمة لعرض موجز بنوعين من البيانات - نص مع وصف وصورة.
onCreateViewHolder سيبدو الكود في الطريقة في الحالة الأكثر شيوعًا كما يلي:
override fun onCreateViewHolder(
parent: ViewGroup, viewType: Int
): RecyclerView.ViewHolder? {
val holder: RecyclerView.ViewHolder
val inflater = LayoutInflater.from(parent.context)
when (viewType) {
TEXT_VIEW_TYPE -> {
holder = TextViewHolder(
inflater.inflate(R.layout.text_item, parent, false)
)
}
IMAGE_VIEW_TYPE -> {
holder = ImageViewHolder(
inflater.inflate(R.layout.image_item, parent, false),
imageClickListener
)
}
else -> {
throw IllegalArgumentException(
"Can't create view holder from view type $viewType"
)
}
}
return holder
}
لماذا هذا سيء؟ الجانب السلبي لهذا التنفيذ ينتهك مبادئ DRY و SOLID (مسؤولية فردية ومغلقة مفتوحة). للاقتناع بهذا ، يكفي إضافة متطلبين: إدخال نوع بيانات جديد (مربع اختيار) وشريط آخر ، حيث سيكون هناك مربعات اختيار وصور فقط.
نواجه خيارًا - استخدام نفس المحول للشريط الثاني أو إنشاء محول جديد؟ بغض النظر عن الحل الذي نختاره ، سيتعين علينا تغيير الكود (حول نفس الشيء ، ولكن في أماكن مختلفة). وسوف يكون من الضروري إضافة VIEW_TYPE جديدة، ViewHolder أساليب جديدة وتحرير:
getItemViewType(), onCreateViewHolder() onBindViewHolder().
إذا قررنا الاحتفاظ بمحول واحد ، فستنتهي التغييرات عند هذا الحد. ولكن إذا تمت إضافة أنواع البيانات الجديدة ذات المنطق الجديد في المستقبل إلى الخلاصة الثانية فقط ، فإن النوع الأول سيكون له وظائف إضافية ، وسيحتاج أيضًا إلى الاختبار ، على الرغم من أنه لم يتغير.
إذا قررنا إنشاء محول جديد ، فسيكون هناك الكثير من الرموز المكررة.
القرار
تسمح لك فئة MergeAdapter الجديدة بدمج محولات مختلفة لأنواع مختلفة من الخلايا. على سبيل المثال ، من حالات الاستخدام الشائعة جدًا عرض القرص الدوار أثناء تحميل البيانات في الخلاصة ، وإذا حدث خطأ في التحميل فجأة ، يتم عرض خلية بها خطأ في نهاية الخلاصة.
يمكن أن يكون حل هذه المشكلة هو استخدام MergeAdapter لنفترض أن لدينا 3 محولات:
val firstAdapter: FirstAdapter = …
val secondAdapter: SecondAdapter = …
val thirdAdapter: ThirdAdapter = …val mergeAdapter = MergeAdapter(firstAdapter, secondAdapter, thirdAdapter)
recyclerView.adapter = mergeAdapter
سيعرض RecyclerView عناصر كل محول بالتتابع ، بنفس الترتيب الذي تم تمريره إلى المنشئ. تسمح لك المحولات المختلفة بفصل المنطق عن الخلايا المختلفة في القائمة. على سبيل المثال ، إذا كنت بحاجة إلى إضافة عنوان إلى القائمة ، فلن تحتاج إلى تنفيذ هذا المنطق في المحول المسؤول عن عرض المحتوى الرئيسي في القائمة ، يمكنك فصل المحولات لأنواع مختلفة من الخلايا. يساعد هذا النهج في تغليف المنطق وإعادة استخدامه في المستقبل لشاشات مختلفة.
اعرض التنزيل في رأس القائمة أو أسفلها.
لعرض حالة التنزيل أعلى القائمة أو أسفلها ، تحتاج إلى إضافة محولات ، على التوالي:
val mergeAdapter = MergeAdapter(headerAdapter, listAdapter, footerAdapter)
recyclerView.adapter = mergeAdapter
تستخدم الخلية العلوية والسفلية نفس التخطيط ومنطق ViewHolder وواجهة المستخدم (إظهار حالة التحميل والإخفاء). بشكل عام ، سيكون كافيًا استخدام مثيلين من نفس المحول لأعلى وأسفل القائمة. يمكن العثور على مثال هنا أو هنا .
باختصار ، بهذه الطريقة البسيطة يمكنك تحسين رمز مشروعك إذا كنت تستخدم محولًا معقدًا مع أنواع مختلفة من الخلايا.
هل أعجبك المقال؟ لا تنس الانضمام إلينا على Telegram ، ويتم نشر مواد مفيدة لمطوري Android والبرامج التعليمية الحديثة على نظام AndroidSchool.ru .