我按照以下指南使用 MotionLayout 创建了一个轮播:https://developer.android.com/training/constraint-layout/motionlayout/carousel
我已经从本指南中获得了一切工作 - 我可以浏览一个旋转木马的项目。
但是,我无法将 onClickListener 添加到我的轮播项目中。我尝试在适配器中设置 onClickListener,如下所示:
carousel.setAdapter(object : Carousel.Adapter {
override fun populate(view: View?, index: Int) {
view.setOnClickListener {
// do something
}
}
})
但是,这会使轮播对滑动没有响应。当我尝试滑动轮播时,它会执行我的 onClick 函数,但不会执行我的 onSwipe 转换。
我的问题是,为轮播项目设置 onClick 功能的正确方法是什么?
在寻找答案时,我看到了一些引用 Carousel.setOnItemClickListener()
的帖子。这正是我需要的,但它似乎已被弃用。
我还看到帖子说要覆盖 onTouchListener 并在 ACTION_UP 事件上运行您的 onClick 代码。我已经尝试了这个代码片段的几个变体,但无法让它工作:
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()
}
}
})
非常感谢任何帮助!
回答1
没有更好的解决方案
您可以像这样覆盖父 MotionLayout 类。拦截幻灯片事件
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
}
}
为我工作