简体   繁体   中英

How to swipe back an item in RecyclerView after swipe

After swiping an item in RecyclerView I want it to go back without swiping it back manually.

Here is an swipeable item in RecyclerView.
Item in RecyclerView

RecyclerView 中的项目

Swiping...

滑动...

After swipe event I want this item to go back, as if it was swiped not far enough, but event must happen. How can I do this?

After swipe

在此处输入图像描述

Here is my SwipeHelper, which keeps background static:

abstract class ProfileSwipeHelper : ItemTouchHelper.SimpleCallback(0,
    ItemTouchHelper.LEFT
) {
    override fun onMove(
        recyclerView: RecyclerView,
        viewHolder: RecyclerView.ViewHolder,
        target: RecyclerView.ViewHolder
    ): Boolean {
        return true
    }

    override fun onSelectedChanged(viewHolder: RecyclerView.ViewHolder?, actionState: Int) {
        if (viewHolder != null) {
            ItemTouchHelper.Callback.getDefaultUIUtil().onSelected((viewHolder as ProfilesAdapter.ViewHolder).foreground)
        }
    }

    override fun onChildDraw(
        c: Canvas,
        recyclerView: RecyclerView,
        viewHolder: RecyclerView.ViewHolder,
        dX: Float,
        dY: Float,
        actionState: Int,
        isCurrentlyActive: Boolean
    ) {
        getDefaultUIUtil().onDraw(c, recyclerView,
            (viewHolder as ProfilesAdapter.ViewHolder).foreground, dX, dY,
            actionState, isCurrentlyActive)

    }

    override fun onChildDrawOver(
        c: Canvas,
        recyclerView: RecyclerView,
        viewHolder: RecyclerView.ViewHolder?,
        dX: Float,
        dY: Float,
        actionState: Int,
        isCurrentlyActive: Boolean
    ) {
        getDefaultUIUtil().onDrawOver(
            c, recyclerView,
            (viewHolder as ProfilesAdapter.ViewHolder).foreground, dX, dY,
            actionState, isCurrentlyActive)
    }
    
    override fun clearView(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder) {
        getDefaultUIUtil().clearView((viewHolder as ProfilesAdapter.ViewHolder).foreground)
    }

}

And here onSwiped event in main activity, only with Toast:

//Main Activity

                val context : Context  = this
        val deleteSwipeHandler1 = object : ProfileSwipeHelper() {
            override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
                Toast.makeText(context, "swiped", Toast.LENGTH_SHORT).show()
            }
        }
        ItemTouchHelper(deleteSwipeHandler1).attachToRecyclerView(rv_profiles)

You can use Multiswipe library. Read complete explanations here . If you want to use Java read this . Below is a concise explanation without using complete options of this library:

add jitpack and Multiswipe library to your project:

in settings.gradle or root build.gradle :

repositories {
    //...
    maven { url 'https://jitpack.io' }
}

in app's build.gradle :

dependencies {
    implementation 'com.github.ygngy:multiswipe:1.2.1'
}

implement MultiSwipe in ViewHolder :

import androidx.recyclerview.widget.RecyclerView
import android.view.View

import com.github.ygngy.multiswipe.MultiSwipe
import com.github.ygngy.multiswipe.LeftSwipeList
import com.github.ygngy.multiswipe.RightSwipeList

class ViewHolder(private val view: View) : RecyclerView.ViewHolder(view), MultiSwipe {
    var mLeftSwipeList: LeftSwipeList? = null
    var mRightSwipeList: RightSwipeList? = null
     
    // todo other ViewHolder codes...

    fun bind() {
       // Each swipe contains of at least an id and an icon
       val likeSwipe = Swipe(
         context = context, // context used to extract default colors and margins from resources
         id = SWIPE_TO_LIKE_ID, // swipe id will be sent to onSwipeDone when swipe is completed
         activeIcon = getDrawable(R.drawable.ic_like_24)!!, // swipe icon
         activeLabel = getString(R.string.like), // OPTIONAL swipe label
         acceptIcon = getDrawable(R.drawable.ic_like_accept_24)!!,// OPTIONAL icon used when swipe displacement is greater than "accept boundary"
         acceptLabel = getString(R.string.like_accept),// OPTIONAL label used when swipe swipe displacement is greater than "accept boundary"
         inactiveIcon = getDrawable(R.drawable.ic_disabled_like_24)!!// OPTIONAL icon used when this swipe could be next swipe
       )

       // Create other swipes (shareSwipe, copySwipe, ...) in a similar way.

      // If row has left swipes, create left swipe list in the desired order like below: 
      mLeftSwipeList = LeftSwipeList (shareSwipe, copySwipe, cutSwipe)
      // If row has right swipes, create right swipe list in the desired order like below:
      mRightSwipeList = RightSwipeList (likeSwipe, editSwipe, delSwipe)
    }
   
   // Don't recreate swipes or any object here 
   override val leftSwipeList: LeftSwipeList?
                get() = mLeftSwipeList
   // Don't recreate swipes or any object here 
   override val rightSwipeList: RightSwipeList?
                get() = mRightSwipeList
    
    
    // Here handle swipe event and/or return some data to MultiSwipeListener 
    override fun onSwipeDone(swipeId: Int): Any? {
        // Instead you may choose to only return data 
        // from this method to consume event at Activity or Fragment
        when(swipeId) {
            SWIPE_TO_SHARE_ID -> {
                // todo share
            }
            SWIPE_TO_COPY_ID -> {
                // todo copy
            }
            //...
        }
        return MyData()// return any data to Activity or Fragment
    }
 }

attach library to recyclerview at activity or fragment:

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle

import com.github.ygngy.multiswipe.MultiSwipeListener
import com.github.ygngy.multiswipe.SwipeDirection
import com.github.ygngy.multiswipe.multiSwiping // importing extension function

class DemoActivity : AppCompatActivity() {
    // todo other activity codes...
    
    override fun onCreate(savedInstanceState: Bundle?) {
        // todo other onCreate codes...

        // attaching Multiswipe to RecycerView
        recyclerView.multiSwiping(
            swipeThreshold = 0.5f, // OPTIONAL, the fraction of view for complete swipe threshold
            object: MultiSwipeListener { // OPTIONAL listener

            // This method is called after onSwipeDone of ViewHolder
            // and data is the returned value of onSwipeDone of ViewHolder
            override fun onSwipeDone(swipeId: Int, data: Any?) {
                // data is the return value of "ViewHolder.onSwipeDone"
                // cast to data you returned from "ViewHolder.onSwipeDone"
                val myData = data as MyData?
                when(swipeId) {
                    SWIPE_TO_SHARE_ID -> shareItem(myData)
                    SWIPE_TO_COPY_ID -> copyItem(myData)
                    //...
                }
            }

            /*** 
              This method will be called when direction changes in each swipe. 
              This method could be used to hide on screen widgets such as FABs. 
              direction may be: 
                 - START (when user opens start side of view), 
                 - END (when user opens end side of view), 
                 - NONE (when swipe is closing without user interaction)
            ***/
            override fun swiping(direction: SwipeDirection, swipeListSize: Int) {
                // here i hide FAB when user is swiping end side actively
                if (direction == SwipeDirection.END) fab.hide() else fab.show()
            }
        })
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM