4 Langkah Menambahkan Swipe Gestures Ke RecyclerViews
Sebagian besar Desain Material adalah cara pengguna berinteraksi dengan elemen visual aplikasi. Oleh karena itu, selain mengetuk dan menekan lama, aplikasi Android yang dibuat dengan baik hari ini diharapkan untuk menangani gerakan sentuhan yang lebih kompleks seperti gesekan dan seret. Ini sangat penting jika aplikasi menggunakan daftar untuk menampilkan datanya.
Dengan menggunakan widget RecyclerView, dan beberapa komponen Android Jetpack lainnya, Anda dapat menangani berbagai gerakan gesekan terkait daftar di aplikasi Anda. Selain itu, hanya dalam beberapa baris kode, Anda dapat mengaitkan animasi Gerakan Material dengan gerakan itu.
Dalam tutorial ini, saya akan menunjukkan kepada Anda cara menambahkan beberapa gerakan menggesek umum, lengkap dengan animasi intuitif, ke daftar Anda.
Prasyarat
Untuk dapat memanfaatkan tutorial ini sebaik-baiknya, Anda membutuhkan:
- Android Studio 3.2.1 atau lebih
- Ponsel atau tablet yang menjalankan Android API level 23 atau lebih tinggi
1. Membuat Daftar
Agar tutorial ini singkat, mari gunakan salah satu templat yang tersedia di Android Studio untuk menghasilkan daftar kita.
Mulailah dengan meluncurkan Android Studio dan membuat proyek baru. Di panduan pembuatan proyek, pastikan Anda memilih opsi Empty Activity.
Dukungan library, kita akan menggunakan Android Jetpack dalam proyek ini. Jadi, setelah proyek dibuat, buka Refactor > Migrate to AndroidX. Saat diminta, tekan tombol Migrate.
Selanjutnya, untuk menambahkan daftar ke proyek, buka File > New > Fragment > Fragment (List). Dalam dialog yang muncul, lanjutkan dan tekan tombol Finish tanpa membuat perubahan apa pun ke nilai default.
Pada titik ini, Android Studio akan membuat fragmen baru yang berisi widget RecyclerView yang sepenuhnya dikonfigurasi. Ini juga akan menghasilkan data dummy untuk ditampilkan di dalam widget. Namun, Anda masih harus menambahkan fragmen ke aktivitas utama Anda secara manual.
Untuk melakukannya, pertama-tama tambahkan ainterface OnListFragmentInteractionListener ke aktivitas utama Anda dan terapkan satu-satunya metode yang dikandungnya.
1: override fun onListFragmentInteraction(
2: item: DummyContent.DummyItem?) {
3: // leave empty
4: }
Selanjutnya, sematkan fragmen di dalam aktivitas dengan menambahkan tag <fragment> berikut ke file activity_main.xml:
1: <fragment android:layout_width="match_parent"
2: android:layout_height="match_parent"
3: android:id="@+id/list_fragment"
4: android:name="com.tutsplus.rvswipes.ItemFragment" />
Pada titik ini, jika Anda menjalankan aplikasi Anda, Anda seharusnya dapat melihat daftar yang terlihat seperti ini:
2. Menambahkan Swipe Gesture (Gerakan Gesek) ke Hapus
Menggunakan class ItemTouchHelper, Anda dapat dengan cepat menambahkan gesek dan seret gerakan ke widget RecyclerView apa pun. Class ini juga menyediakan animasi default yang berjalan secara otomatis setiap kali gerakan yang valid terdeteksi.
Class ItemTouchHelper membutuhkan turunan dari class ItemTouchHelper.Callback abstrak untuk dapat mendeteksi dan menangani gerakan. Meskipun Anda dapat menggunakannya secara langsung, lebih mudah menggunakan kelas pembungkus yang disebut SimpleCallback. Ini abstrak juga, tetapi Anda akan memiliki lebih sedikit metode untuk menimpanya.
Buat instance baru dari class SimpleCallback di dalam metode onCreateView () dari class ItemFragment. Sebagai argumen untuk konstruktornya, Anda harus melewati arah gesek yang Anda inginkan. Untuk saat ini, berikan RIGHT untuk itu sehingga menangani gerakan swipe-kanan.
1: val myCallback = object: ItemTouchHelper.SimpleCallback(0,
2: ItemTouchHelper.RIGHT) {
3: // More code here
4: }
Class memiliki dua metode abstrak, yang harus Anda timpa: metode onMove (), yang mendeteksi hambatan, dan metode onSwiped (), yang mendeteksi gesekan. Karena kita tidak akan menangani gerakan seret apa pun hari ini, pastikan Anda mengembalikan false di dalam metode onMove ().
1: override fun onMove(
2: recyclerView: RecyclerView,
3: viewHolder: RecyclerView.ViewHolder,
4: target: RecyclerView.ViewHolder
5: ): Boolean = false
6: override fun onSwiped(viewHolder: RecyclerView.ViewHolder,
7: direction: Int) {
8: // More code here
9: }
Di dalam metode onSwiped (), Anda bisa menggunakan properti adapterPosition untuk menentukan indeks item daftar yang digesek. Karena kita menerapkan gerakan gesek-untuk-menghapus sekarang, berikan indeks ke metode removeAt () dari daftar dummy untuk menghapus item.
1: DummyContent.ITEMS.removeAt(viewHolder.adapterPosition)
Selain itu, Anda harus meneruskan indeks yang sama ke metode notifyItemRemoved () pada adaptor widget RecyclerView untuk memastikan bahwa item tidak dirender lagi. Melakukannya juga menjalankan animasi penghapusan item default.
1: adapter?.notifyItemRemoved(viewHolder.adapterPosition)
Pada tahap ini, objek SimpleCallback siap. Yang perlu Anda lakukan sekarang adalah membuat objek ItemTouchHelper dengannya dan pasang widget RecyclerView ke sana.
1: val myHelper = ItemTouchHelper(myCallback)
2: myHelper.attachToRecyclerView(this)
Jika Anda menjalankan aplikasi sekarang, Anda dapat menghapus item dari daftar.
3. Revealing Tampilan Latar Belakang
Meskipun gerakan menggesek untuk menghapus sangat intuitif, beberapa pengguna mungkin tidak yakin apa yang terjadi ketika mereka melakukan gerakan. Oleh karena itu, Material Design guidelines mengatakan bahwa gerakan itu juga harus secara progresif mengungkapkan pandangan yang tersembunyi di balik item, yang dengan jelas menunjukkan apa yang akan terjadi selanjutnya. Biasanya, tampilan latar belakang hanyalah sebuah ikon yang menampilkan tempat sampah.
Untuk menambahkan ikon tempat sampah ke proyek Anda, buka File> New> Vector Asset dan pilih ikon bernama delete.
Anda sekarang bisa mendapatkan referensi ke ikon di kode Kotlin Anda dengan memanggil metode getDrawable (). Jadi tambahkan baris berikut ke metode onCreateView () dari class ItemFragment:
1: val trashBinIcon = resources.getDrawable(
2: R.drawable.ic_delete_black_24dp,
3: null
4: )
Menampilkan tampilan di belakang item daftar sedikit rumit karena Anda perlu menggambar secara manual sambil juga memastikan bahwa batasnya sesuai dengan batas wilayah yang semakin terungkap.
Ganti metode onChildDraw () dari implementasi SimpleCallback Anda untuk mulai menggambar.
1: override fun onChildDraw(
2: c: Canvas,
3: recyclerView: RecyclerView,
4: viewHolder: RecyclerView.ViewHolder,
5: dX: Float,
6: dY: Float,
7: actionState: Int,
8: isCurrentlyActive: Boolean
9: ) {
10: // More code here
11: super.onChildDraw(c, recyclerView, viewHolder,
12: dX, dY, actionState, isCurrentlyActive)
13: }
Dalam kode di atas, panggilan ke metode onChildDraw () dari superclass adalah penting. Tanpanya, item daftar Anda tidak akan bergerak saat digesek.
Karena kita hanya menangani gerakan menggesek-kanan, koordinat X dari sudut kiri atas dan kiri bawah dari tampilan latar belakang akan selalu nol. Sebaliknya, koordinat X sudut kanan atas dan kanan bawah harus sama dengan parameter dX, yang menunjukkan seberapa banyak item daftar telah dipindahkan oleh pengguna.
Untuk menentukan koordinat Y dari semua sudut, Anda harus menggunakan properti top dan bottom dari salah satu tampilan yang ada di dalam objek viewHolder.
Dengan menggunakan semua koordinat ini, kini Anda dapat menentukan wilayah klip persegi panjang. Kode berikut ini menunjukkan kepada Anda bagaimana menggunakan metode clipRect () dari objek Canvas untuk melakukannya:
1: c.clipRect(0f, viewHolder.itemView.top.toFloat(),
2: dX, viewHolder.itemView.bottom.toFloat())
Meskipun Anda tidak harus melakukannya, adalah ide yang bagus untuk membuat wilayah klip terlihat dengan memberikan warna latar belakang. Inilah cara Anda dapat menggunakan metode drawColor () untuk membuat wilayah klip menjadi abu-abu saat jarak gesek kecil dan merah saat lebih besar.
1: if(dX < width / 3)
2: c.drawColor(Color.GRAY)
3: else
4: c.drawColor(Color.RED)
Anda sekarang harus menentukan batasan ikon tempat sampah. Batas ini harus menyertakan margin yang cocok dengan teks yang ditampilkan dalam daftar item. Untuk menentukan nilai margin dalam piksel, gunakan metode getDimension () dan kirimkan text_margin ke sana.
1: val textMargin = resources.getDimension(R.dimen.text_margin)
2: .roundToInt()
Anda dapat menggunakan kembali koordinat sudut kiri atas area klip sebagai koordinat sudut kiri atas ikon. Mereka harus, bagaimanapun, diimbangi oleh textMargin. Untuk menentukan koordinat sudut kanan bawahnya, gunakan lebar dan tinggi intrinsiknya. Begini caranya:
1: trashBinIcon.bounds = Rect(
2: textMargin,
3: viewHolder.itemView.top + textMargin,
4: textMargin + trashBinIcon.intrinsicWidth,
5: viewHolder.itemView.top + trashBinIcon.intrinsicHeight
6: + textMargin
7: )
Terakhir, gambar ikon dengan memanggil metode draw ().
1: trashBinIcon.draw(c)
Jika Anda menjalankan aplikasi lagi, Anda harus dapat melihat ikon ketika Anda menggesek untuk menghapus item daftar.
4. Menambahkan Gerakan Swipe-to-Refresh
Gerakan gesek-untuk-menyegarkan, juga dikenal sebagai gerakan tarik untuk-menyegarkan, telah menjadi sangat populer akhir-akhir ini sehingga Android Jetpack memiliki komponen khusus untuk itu. Ini disebut SwipeRefreshLayout, dan memungkinkan Anda untuk dengan cepat mengaitkan isyarat dengan widget RecyclerView, ListView, atau GridView.
Untuk mendukung gerakan gesek-untuk-menyegarkan di widget RecyclerView Anda, Anda harus membuatnya sebagai anak dari widget SwipeRefreshLayout. Jadi buka file fragment_item_list.xml, tambahkan tag <SwipeRefreshLayout> ke dalamnya, dan pindahkan tag <RecycleView> di dalamnya. Setelah Anda melakukannya, konten file akan seperti ini:
1: <?xml version="1.0" encoding="utf-8"?>
2: <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
3: xmlns:android="https://schemas.android.com/apk/res/android"
4: xmlns:app="http://schemas.android.com/apk/res-auto"
5: xmlns:tools="http://schemas.android.com/tools"
6: android:layout_width="match_parent"
7: android:layout_height="match_parent">
8: <androidx.recyclerview.widget.RecyclerView
9: android:id="@+id/list"
10: android:name="com.tutsplus.rvswipes.ItemFragment"
11: android:layout_width="match_parent"
12: android:layout_height="match_parent"
13: android:layout_marginLeft="16dp"
14: android:layout_marginRight="16dp"/>
15: </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
Fragmen daftar mengasumsikan bahwa widget RecyclerView adalah elemen root dari tata letaknya. Karena ini tidak benar lagi, Anda perlu membuat beberapa perubahan dalam metode onCreateView () dari kelas ItemFragment. Pertama, ganti baris pertama metode, yang mengembang tata letak, dengan kode berikut:
1: val srLayout: SwipeRefreshLayout =
2: inflater.inflate(
3: R.layout.fragment_item_list, container, false
4: ) as SwipeRefreshLayout
5: val view = srLayout.findViewById<RecyclerView>(R.id.list)
Selanjutnya, ubah baris terakhir metode untuk mengembalikan widget SwipeRefreshLayout alih-alih widget RecyclerView.
1: return srLayout
Jika Anda mencoba menjalankan aplikasi sekarang, Anda akan dapat melakukan gerakan geser vertikal dan mendapatkan umpan balik visual. Isi daftar tidak akan berubah. Untuk benar-benar menyegarkan daftar, Anda harus mengaitkan objek OnRefreshListener dengan widget SwipeRefreshLayout.
1: srLayout.setOnRefreshListener {
2: // More code here
3: }
Di dalam listener, Anda bebas mengubah data yang ditampilkan daftar berdasarkan kebutuhan Anda. Untuk saat ini, karena kami bekerja dengan data dummy, mari kita kosongkan daftar item dummy dan memuatnya dengan 25 item dummy baru. Kode berikut menunjukkan kepada Anda bagaimana melakukannya:
1: DummyContent.ITEMS.clear()
2: for(i in 1..25) {
3: DummyContent.ITEMS.add(
4: DummyContent.DummyItem("$i", "Item $i", "")
5: )
6: }
Setelah memperbarui data, Anda harus ingat untuk memanggil metode notifyDataSetChanged () untuk membiarkan adapter widget RecyclerView tahu bahwa ia harus menggambar ulang daftar.
1: view.adapter?.notifyDataSetChanged()
Secara default, segera setelah pengguna melakukan gerakan swipe-to-refresh, widget SwipeRefreshLayout menampilkan indikator progres animasi. Oleh karena itu, setelah Anda memperbarui daftar, Anda harus ingat untuk menghapus indikator dengan mengatur properti isRefreshing dari widget ke false.
1: srLayout.isRefreshing = false
Jika Anda menjalankan aplikasi sekarang, menghapus beberapa item daftar, dan melakukan gerakan swipe-to-refresh, Anda akan melihat daftar reset sendiri.
Kesimpulan
Desain Material telah ada selama beberapa tahun sekarang, dan sebagian besar pengguna saat ini mengharapkan Anda untuk menangani banyak gerakan yang disebutkannya. Untungnya, melakukan itu tidak membutuhkan banyak usaha. Dalam tutorial ini, Anda belajar cara menerapkan dua gerakan menggesek yang sangat umum. Anda juga belajar cara mengungkapkan tampilan yang disembunyikan di belakang item daftar yang disapu secara progresif.
Anda dapat mempelajari lebih lanjut tentang gerakan dan Gerakan Material dengan merujuk ke panduan Desain Gesture.






Post a Comment
Untuk menyisipkan kode pendek, gunakan <i rel="code"> ... KODE ... </i>
Untuk menyisipkan kode panjang, gunakan <i rel="pre"> ... KODE ... </i>
Untuk menyisipkan gambar, gunakan <i rel="image"> ... URL GAMBAR ... </i>