syamsu.dev

Implementasi Swipe Gesture pada Android RecyclerView

2018-03-16

Touch Gesture Pada umumnya sebuah aplikasi android yang punya tampilan list menerapkan swipe gesture untuk menghilangkannya dari list. Ada banyak cara di internet bagaimana implementasi gesture ini pada RecyclerView. Salah satunya menggunakan ItemTouchHelper untuk translasi sebuah item RecyclerView. Translasi di sini maksudnya adalah memindahkan semua titik dari sebuah objek di view ke arah tertentu dengan jarak yang sama. Contohnya pada swipe gesture yang akan kita implementasikan kali ini. Supaya user dapat melakukan swipe pada sebuah item, maka item yang bersangkutan membutuhkan kemampuan untuk melakukan translasi.

Untuk membuat sebuah view dapat melakukannya, pertama kita buat implementasi dari ItemTouchHelper.SimpleCallback.

1class RecyclerItemTouchHelper(

2 private val context: Context,

3 private val listener: SwipeListener

4) : ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.RIGHT) { //only allow swipe to right

5interface SwipeListener {

6 fun delete(position: Int)

7}

8...

9override fun onMove(

10 recyclerView: RecyclerView?,

11 viewHolder: RecyclerView.ViewHolder?,

12 target: RecyclerView.ViewHolder?

13): Boolean {

14 return false

15}

16override fun onSwiped(viewHolder: RecyclerView.ViewHolder?, direction: Int) {

17 this.listener.delete(viewHolder!!.adapterPosition)

18}

Pada contoh di atas, saya membuatnya hanya memperbolehkan swipe gesture ke kanan. Jika ingin implementasi kanan dan kiri, pada baris kedua kita bisa menggantinya seperti berikut

: ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.RIGHT | ItemTouchHelper.RIGHT)

Pada parameter constructor pertama diberikan angka nol untuk membuatnya tidak bisa di-drag secara vertikal. Kita tidak memerlukan drag gesture, jadi pada method onMove() di-return false. Method onSwiped() akan dipanggil ketika sebuah gesture swipe berada pada kondisi sudah di-swipe (swiped). Di sini kita melakukan aksi delete dengan memanggil method dari interface.

Kemudian, untuk menggambar background warna abu-abu dan icon archive dari item yang di swipe. Lakukan override pada method onChildDraw seperti berikut

1override 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 val itemView = viewHolder.itemView

11 val itemHeight = itemView.height

12 val background = ColorDrawable()

13 background.color = Color.DKGRAY

14 background.setBounds(itemView.left, itemView.top, itemView.right, itemView.bottom)

15 background.draw(c)

16 val archiveIcon = ContextCompat.getDrawable(context, R.drawable.ic_archive_white_24dp)

17 val intrinsicWidth = archiveIcon.intrinsicWidth

18 val intrinsicHeight = archiveIcon.intrinsicHeight

19 val archiveIconTop = itemView.top + (itemHeight - intrinsicHeight) / 2

20 val archiveIconMargin = (itemHeight - intrinsicHeight) / 2

21 val archiveIconLeft = itemView.left + archiveIconMargin

22 val archiveIconRight = itemView.left + archiveIconMargin - intrinsicWidth

23 val archiveIconBottom = archiveIconTop + intrinsicHeight

24 archiveIcon.setBounds(archiveIconLeft, archiveIconTop, archiveIconRight, archiveIconBottom)

25 archiveIcon.draw(c)

26 super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive)

27}

Method di atas menggambar warna background dan icon ke canvas milik view yang di-swipe oleh user.

Secara keseluruhan, class RecyclerItemTouchHelper tersebut menjadi seperti ini

1package net.mnsam.antnote.feature.list.recycler

2import android.content.Context

3import android.graphics.Canvas

4import android.graphics.Color

5import android.graphics.drawable.ColorDrawable

6import android.support.v4.content.ContextCompat

7import android.support.v7.widget.RecyclerView

8import android.support.v7.widget.helper.ItemTouchHelper

9import net.mnsam.antnote.R

10/**

11 * Created by Mochamad Noor Syamsu on 3/9/18.

12 */

13class RecyclerItemTouchHelper(private val context: Context, private val listener: SwipeListener)

14 : ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.RIGHT) {

15 interface SwipeListener {

16 fun delete(position: Int)

17 }

18 override fun onChildDraw(

19 c: Canvas,

20 recyclerView: RecyclerView,

21 viewHolder: RecyclerView.ViewHolder,

22 dX: Float,

23 dY: Float,

24 actionState: Int,

25 isCurrentlyActive: Boolean

26 ) {

27 val itemView = viewHolder.itemView

28 val itemHeight = itemView.height

29 val background = ColorDrawable()

30 background.color = Color.DKGRAY

31 background.setBounds(itemView.left, itemView.top, itemView.right, itemView.bottom)

32 background.draw(c)

33 val archiveIcon = ContextCompat.getDrawable(context, R.drawable.ic_archive_white_24dp)

34 val intrinsicWidth = archiveIcon.intrinsicWidth

35 val intrinsicHeight = archiveIcon.intrinsicHeight

36 val archiveIconTop = itemView.top + (itemHeight - intrinsicHeight) / 2

37 val archiveIconMargin = (itemHeight - intrinsicHeight) / 2

38 val archiveIconLeft = itemView.left + archiveIconMargin

39 val archiveIconRight = itemView.left + archiveIconMargin - intrinsicWidth

40 val archiveIconBottom = archiveIconTop + intrinsicHeight

41 archiveIcon.setBounds(archiveIconLeft, archiveIconTop, archiveIconRight, archiveIconBottom)

42 archiveIcon.draw(c)

43 super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive)

44 }

45 override fun onMove(

46 recyclerView: RecyclerView?,

47 viewHolder: RecyclerView.ViewHolder?,

48 target: RecyclerView.ViewHolder?

49 ): Boolean {

50 return false

51 }

52 override fun onSwiped(viewHolder: RecyclerView.ViewHolder?, direction: Int) {

53 this.listener.delete(viewHolder!!.adapterPosition)

54 }

55}

Dari callback ItemTouchHelper yang telah dibuat. Kita implementasikan ke activity yang bersangkutan.

1val swipeListener = object : RecyclerItemTouchHelper.SwipeListener {

2 override fun delete(position: Int) {

3 presenter.onArchiveNote(position)

4 }

5}

6val itemTouchHelper = ItemTouchHelper(RecyclerItemTouchHelper(this, swipeListener))

7itemTouchHelper.attachToRecyclerView(listItem) //attach to RecyclerView whose id is listItem

Di activity kita buat implementasi dari interface listener yang ada untuk dimasukkan ke constructor callback tadi. listItem di sini adalah id RecyclerView-nya.

Sampai di sini, kita sudah menjangkau dasar - dasar implementasi swipe gesture ini. Untuk implementasi dari penjelasan di atas secara keseluruhan, kamu bisa mengeksplorasi sumber kodenya di github project Ant Note.

Terima kasih sudah membaca.

Sumber gambar

android, itemtouchhelper, pemrograman, recyclerview, swipe