Pendekatan alternatif untuk menampilkan beban selama pagination

gambar

Bekerja dengan pemuatan halaman-demi-halaman dalam aplikasi seluler adalah topik yang cukup sederhana dan tidak memiliki jebakan.

Pengembang sering menghadapi tugas serupa dan, karenanya, berulang kali melakukan hal yang sama membosankan dan malas.

Tetapi tugas apa pun yang paling biasa pun dapat diselesaikan dengan cara lain yang lebih menarik untuk mendapatkan pengetahuan baru dan hanya meregangkan otak Anda.

Pagination


Singkatnya, semua pekerjaan pada implementasi pagination terdiri dari item yang tercantum di bawah ini:

  1. Tambahkan pendengar ke tampilan pendaur ulang;
  2. Unduh data primer;
  3. Menangkap panggilan balik saat pengguna menelusuri daftar;
  4. Perlihatkan unduhan dalam daftar setelah semua item;
  5. Kirim permintaan untuk item baru;
  6. Tampilkan data lagi.

Dalam kasus kami, mekanisme halaman halaman diimplementasikan, tetapi tidak ada tampilan beban saat pengguna sedang menggulir daftar.

Oke, melakukan ini sekali dalam satu aplikasi bukan masalah. Jika ada beberapa layar di mana fungsi ini diperlukan, maka Anda dapat menulis adaptor dasar yang dapat bekerja dengan jenis tampilan tambahan.

Tapi, bagaimana jika tugasnya agak lebih rumit?

Katakanlah ada beberapa proyek bukan baru yang memiliki satu modul inti dengan fungsi dasar.

Karena proyek jauh dari tahun pertama, sebagai akibatnya, banyak kode warisan telah diakumulasikan terkait dengan tugas ini, yaitu, banyak adaptor dengan kelas dasar yang berbeda.

Bagaimana saya bisa menyelesaikan masalah?


Buat adaptor basis baru yang akan dapat menunjukkan kemajuan pengunduhan, tulis ulang semua + adaptor lama yang menggunakan adaptor, karena Anda harus mengontrol status tampilan beban pada setiap layar, di setiap presenter atau tampilan.

Ini bisa sangat memakan waktu. Dan juga refactoring besar dapat menyebabkan sejumlah kesalahan baru, terutama jika cakupan pengujian dalam proyek cenderung nol. Plus, beban tinggi pada departemen QA dengan pengujian regresi semua layar dengan pagination untuk beberapa aplikasi.

Akan sangat bagus untuk menulis kode seperti itu yang membutuhkan waktu minimum dari klien pengembangan untuk mengintegrasikan solusi dasar dalam fitur-fiturnya. Agar tidak harus menerapkan logika kontrol untuk menampilkan progres pemuatan - perlihatkan dan sembunyikan.

Pada titik ini, saya berpikir untuk menggunakan kelas ItemDecoration .

Mengapa tidak menggunakan kelas ini untuk merangkum semua pekerjaan yang terkait

  • menentukan kapan harus menunjukkan beban dan kapan menyembunyikannya
  • menggambar kemajuan unduhan

Sayangnya, tidak ada satu pun solusi siap pakai yang ditemukan di Internet - entah tidak ada yang mencoba mengimplementasikannya, atau sama sekali tidak berbagi pengalaman setelah implementasi.

Apa yang diperlukan untuk mengimplementasikan tampilan pemuatan selama pagination menggunakan ItemDecoration?


  • Indent untuk membuat beban;
  • Memahami implementasi ItemDecoration ketika kita perlu menunjukkan kemajuan;
  • Gambar unduhan;

Lekukan


Pengembang mana pun yang telah membuat SpacingItemDecoration setidaknya sekali tahu cara membuat indentasi. Metode getitemOffsets ItemDecoration akan membantu kami dengan ini:

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

Untuk setiap elemen daftar, kita dapat menambahkan indentasi di kedua sisi. Khususnya, dalam kasus kami, kami perlu memahami bahwa pengguna telah menggulung daftar ke ujung dan pada elemen terakhir indentasi dari bawah sama dengan nilai progres unduhan yang ditampilkan di masa mendatang + indentasi dari progres itu sendiri.

Bagaimana memahami bahwa daftar tersebut digulir ke bawah?

Kode di bawah ini akan membantu kami dalam hal ini:

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

Secara total, kami memiliki kode untuk mendefinisikan dan mengimplementasikan indentasi:

  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 } 

Sepertiga pekerjaan selesai!

Kami menentukan waktu menampilkan progres unduhan dan memanggil render progres


Metode ItemDecoration onDrawOver akan membantu kami dengan ini:

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

Metode onDrawOver berbeda dari metode onDraw hanya dalam urutan rendering. Dekorasi OnDrawOver hanya akan diberikan setelah item daftar itu sendiri telah ditarik.

Dalam metode onDrawOver, kita perlu memahami pada titik mana kita perlu menggambar kemajuan, pada titik mana untuk menghapusnya dan menyebabkan pembaruan pada item daftar untuk menyembunyikan indentasi yang sudah indentasi.

Kode untuk mengimplementasikan tindakan yang dijelaskan di atas:

  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 } 

Menggambar kemajuan


Kode rendering cukup banyak dan akan disajikan dalam file terpisah, tautan yang akan saya sajikan di bawah ini.

Saya hanya ingin membahas nuansa yang diperlukan untuk implementasi.

Semua pekerjaan menggambar dilakukan di atas kanvas. Dengan demikian, akan diperlukan untuk mengkonfigurasi turunan dari objek Paint dan menggambar busur, yang menunjukkan sudut awal dan akhir.

Nuansa penting adalah bahwa untuk membuat sebanyak mungkin mirip dengan ProgressBar biasa, Anda perlu membuat analog Anda sendiri dari interpolator sehingga animasi rendering terjadi secara non-linear.

Untuk memahami karya interpolator dan memahami apa yang ingin Anda dapatkan dari animasi Anda, saya sarankan Anda membiasakan diri dengan grafik yang menggambarkan karya berbagai jenis interpolator, misalnya, dalam artikel ini

Referensi Kode:

PaginationLoadingDecoration
PaginationProgressDrawer

Jika perlu, Anda bisa membuat antarmuka ProgressDrawer dan mengganti implementasi di PaginationLoadingDecoration.

Unduh Video Demo:


Terima kasih telah membaca, menikmati coding :)

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


All Articles