我按照本指南使用 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()
}
}
})
非常感谢任何帮助!
没有更好的解决方案
您可以像这样重写父 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 : [email protected]
* @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(ev.x - mInitX)
val moveY = abs(ev.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
}
}
为我工作