简体   繁体   中英

How to add click listener to Carousel item

I've created a Carousel using MotionLayout by following this guide: https://developer.android.com/training/constraint-layout/motionlayout/carousel

I've gotten everything from this guide working - I can swipe through a carousel of items.

However, I'm having trouble adding an onClickListener to my carousel's items. I've tried setting the onClickListener in the adapter like so:

carousel.setAdapter(object : Carousel.Adapter {
  override fun populate(view: View?, index: Int) {
    view.setOnClickListener {
      // do something
    }
  }
})

However, this makes the carousel unresponsive to swiping. When I try to swipe the carousel it executes my onClick function but doesn't execute my onSwipe transition.

My question is, what is the proper way to set an onClick function for a Carousel item?

While searching for an answer, I've seen a few posts that reference Carousel.setOnItemClickListener() . This is exactly what I need, but it seems to have been deprecated.

I've also seen posts to say to override onTouchListener and run your onClick code on the ACTION_UP event. I've tried a couple variations of this code snippet, but haven't been able to get it to work:

carousel.setAdapter(object : Carousel.Adapter {
  override fun populate(view: View?, index: Int) {
    view.setOnTouchListener { view, motionEvent ->
      if(motionEvent.action == MotionEvent.ACTION_UP) {
        // do something
      }
      view.performClick()
    }
  }
})

Would really appreciate any help!

No better solution

You could have override parent MotionLayout class like this.Intercept the slide event

import android.content.Context
import android.util.AttributeSet
import android.view.MotionEvent
import androidx.constraintlayout.motion.widget.MotionLayout
import kotlin.math.abs

/**
 * @author : litao
 * @email  : onresume@live.com
 * @date   : 2022/5/31 5:31 下午
 */
class TestMotionLayout constructor(
    context: Context,
    attrs: AttributeSet?,
    defStyleAttr: Int,
) : MotionLayout(context, attrs, defStyleAttr) {

    private var mInitX = 0f
    private var mInitY = 0f

    private var mTouchSlop = 10

    override fun onInterceptTouchEvent(ev: MotionEvent): Boolean {

        when (ev.actionMasked) {
            MotionEvent.ACTION_DOWN -> {
                mInitX = ev.x
                mInitY = ev.y
            }
            MotionEvent.ACTION_MOVE -> {
                val moveX = abs(x - mInitX)
                val moveY = abs(y - mInitY)

                if (moveX > mTouchSlop || moveY > mTouchSlop){
                 
                    val obtain = MotionEvent.obtain(ev)
                    obtain.action = MotionEvent.ACTION_DOWN
                    dispatchTouchEvent(obtain)
                    onTouchEvent(obtain)
                    return true
                }
            }
            MotionEvent.ACTION_UP -> {
            }
        }
        return false
    }


}

Worked for me

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