طريقة بديلة لعرض الحمل أثناء ترقيم الصفحات

صورة

يعد العمل مع التحميل بصفحة صفحة في تطبيقات الأجهزة المحمولة موضوعًا بسيطًا إلى حد ما ولا يحتوي على أي عيوب.

يواجه المطور مهمة مماثلة في كثير من الأحيان ، وبالتالي ، مرارًا وتكرارًا يفعل نفس الشيء مملًا وكسولًا.

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

ترقيم الصفحات


باختصار ، كل العمل على تنفيذ ترقيم الصفحات يتكون من العناصر المدرجة أدناه:

  1. إضافة المستمع لعرض إعادة التدوير.
  2. تحميل البيانات الأولية ؛
  3. قم بإجراء رد اتصال عندما يقوم المستخدم بالتمرير خلال القائمة ؛
  4. إظهار التنزيل في القائمة بعد كل العناصر ؛
  5. إرسال طلب لعناصر جديدة ؛
  6. عرض البيانات مرة أخرى.

في حالتنا ، تم تنفيذ آلية ترحيل الصفحات ، ولكن لم يكن هناك عرض للحمل أثناء قيام المستخدم بالتمرير خلال القائمة.

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

ولكن ، ماذا لو كانت المهمة أكثر تعقيدًا إلى حد ما؟

دعنا نقول أن هناك العديد من المشاريع غير الجديدة التي تحتوي على وحدة أساسية واحدة ذات وظائف أساسية.

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

كيف يمكنني حل المشكلة؟


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

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

سيكون من الرائع كتابة مثل هذا الرمز الذي يتطلب الحد الأدنى من الوقت من عميل التطوير لدمج الحل الأساسي في ميزته. حتى لا تضطر إلى تنفيذ منطق التحكم في عرض تقدم التحميل - العرض والاختباء.

في هذه المرحلة ، فكرت في استخدام فئة ItemDecoration .

لماذا لا تستخدم هذه الفئة لتغليف كل الأعمال المتعلقة بها

  • تحديد وقت إظهار الحمل ومتى يتم إخفاؤه
  • رسم تقدم التحميل

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

ما المطلوب لتنفيذ عرض التحميل أثناء ترقيم الصفحات باستخدام ItemDecoration؟


  • المسافة البادئة لتقديم الحمل ؛
  • فهم تنفيذ ItemDecoration عندما نحتاج إلى إظهار التقدم ؛
  • رسم التحميل

المسافة البادئة


أي مطور قام بإنشاء SpacingItemDecoration مرة واحدة على الأقل يعرف كيفية المسافة البادئة. ستساعدنا طريقة ItemDecoration getItemOffsets في:

override fun getItemOffsets(outRect: Rect, view: View, recyclerView: RecyclerView, state: RecyclerView.State) { super.getItemOffsets(outRect, view, parent, state) } 

لأي عنصر في القائمة ، يمكننا إضافة مسافات بادئة على أي جانب. على وجه التحديد ، في حالتنا ، نحتاج إلى أن نفهم أن المستخدم قد قام بتحريك القائمة إلى النهاية وفي المسافة البادئة للعنصر الأخير من أسفل مساوية لقيمة تقدم التنزيل الذي تم عرضه في المستقبل + المسافات البادئة من التقدم نفسه.

كيف نفهم أن القائمة يتم تمريرها إلى أسفل؟

الكود أدناه سوف يساعدنا في هذا:

  private fun isLastItem(recyclerView: RecyclerView, view: View): Boolean { val lastItemPos = recyclerView.getChildAdapterPosition(view) return lastItemPos == recyclerView.adapter!!.itemCount - 1 } 

في المجموع ، لدينا رمز لتحديد المسافة البادئة وتنفيذها:

  override fun getItemOffsets(outRect: Rect, view: View, recyclerView: RecyclerView, state: RecyclerView.State) { super.getItemOffsets(outRect, view, recyclerView, state) when (isLastItem(recyclerView, view)) { true -> outRect.set(Rect(0, 0, 0, 120)) else -> outRect.set(Rect(0, 0, 0, 0)) } } private fun isLastItem(recyclerView: RecyclerView, view: View): Boolean { val lastItemPos = recyclerView.getChildAdapterPosition(view) return lastItemPos == recyclerView.adapter!!.itemCount - 1 } 

ثلث العمل يتم!

نحدد وقت عرض تقدم التنزيل وندعو إلى تقديم التقدم


ستساعدنا طريقة ItemDecoration onDrawOver في:

  override fun onDrawOver(canvas: Canvas, recyclerView: RecyclerView, state: RecyclerView.State) { super.onDrawOver(canvas, recyclerView, state) } 

يختلف أسلوب onDrawOver عن أسلوب onDraw فقط في ترتيب العرض. سيتم تقديم زينة OnDrawOver فقط بعد رسم عنصر القائمة نفسه.

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

رمز لتنفيذ الإجراءات المذكورة أعلاه:

  override fun onDrawOver(canvas: Canvas, recyclerView: RecyclerView, state: RecyclerView.State) { super.onDrawOver(canvas, recyclerView, state) when (showLoading(recyclerView)) { true -> { PaginationProgressDrawer.drawSpinner(recyclerView, canvas) isProgressVisible = true } else -> { if (isProgressVisible) { isProgressVisible = false recyclerView.invalidateItemDecorations() } } } } private fun showLoading(recyclerView: RecyclerView): Boolean { val manager = recyclerView.layoutManager as LinearLayoutManager val lastVisibleItemPos = manager.findLastCompletelyVisibleItemPosition() return lastVisibleItemPos != -1 && lastVisibleItemPos >= recyclerView.adapter!!.itemCount - 1 } 

رسم التقدم


رمز العرض كبير جدًا وسيتم تقديمه في ملف منفصل ، وهو رابط سأقدمه أدناه.

أريد أن أتناول فقط الفروق الدقيقة اللازمة للتنفيذ.

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

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

لفهم عمل المترجمين وفهم ما تريد الحصول عليه من الرسوم المتحركة الخاصة بك ، أوصي بأن تتعرف على الرسوم البيانية التي تصور عمل أنواع مختلفة من المترجمين ، على سبيل المثال ، في هذه المقالة

مراجع الكود:

PaginationLoadingDecoration
PaginationProgressDrawer

إذا لزم الأمر ، يمكنك إنشاء واجهة ProgressDrawer واستبدال التطبيقات في PaginationLoadingDecoration.

تنزيل الفيديو التجريبي:


شكرا للقراءة ، استمتع الترميز :)

Source: https://habr.com/ru/post/ar468877/


All Articles