我正在尝试为cardView设置一个触摸监听器(由于运动布局,它也是可滑动的),问题是,如果我在onTouchListener中返回true,当event.action == ACTION_DOWN时(这样我就可以在用户从cardView上抬起手指)该cardView上的滑动动画不起作用。当用户抬起手指时,我需要执行我的逻辑,因为如果我在 ACTION_DOWN 上执行逻辑,那么在用户刷卡视图时,我的逻辑也会被执行(我希望仅当用户点击时才执行逻辑)在卡片上查看)。
这是 xml 布局:
<androidx.constraintlayout.motion.widget.MotionLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
app:motionDebug="SHOW_ALL"
android:id="@+id/matchingMotionLayout"
android:layout_width="match_parent"
app:layoutDescription="@xml/matching_scene"
android:layout_height="match_parent">
<com.google.android.material.card.MaterialCardView
android:id="@+id/cardTwo"
android:layout_width="320dp"
android:layout_height="480dp"
app:cardBackgroundColor="@color/design_default_color_secondary"
app:cardCornerRadius="24dp"
app:layout_constraintBottom_toTopOf="@id/dislikeButton"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/matchingWithTitle"
app:layout_constraintVertical_bias="0.4">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/bottomImage"
android:layout_height="0dp"
android:layout_width="match_parent"
android:scaleType="centerCrop"
app:layout_constraintBottom_toTopOf="@id/bottomInterestPointName"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/bottomInterestPointName"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:elevation="1dp"
android:gravity="center_horizontal"
android:paddingVertical="24dp"
android:textColor="@android:color/white"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
tools:text="Restaurant Name" />
</androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.card.MaterialCardView>
<com.google.android.material.card.MaterialCardView
android:id="@+id/cardOne"
android:layout_width="320dp"
android:layout_height="480dp"
app:layout_constraintBottom_toTopOf="@id/dislikeButton"
app:cardBackgroundColor="@color/md_theme_light_primary"
app:cardCornerRadius="24dp"
app:layout_constraintTop_toBottomOf="@id/matchingWithTitle"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintVertical_bias="0.4">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/cardOneLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/topImage"
android:layout_height="0dp"
android:scaleType="centerCrop"
android:layout_width="match_parent"
app:layout_constraintBottom_toTopOf="@id/topInterestPointName"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/topInterestPointName"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:elevation="1dp"
android:gravity="center_horizontal"
android:paddingVertical="24dp"
android:textColor="@android:color/white"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
tools:text="Restaurant Name" />
</androidx.constraintlayout.widget.ConstraintLayout>
</com.jhn.restaurantpicker.ui.core.TestCardView>
...
</com.jhn.restaurantpicker.ui.core.TestMotionLayout>
这是我的运动场景转换:
<MotionScene xmlns:android="http://schemas.android.com/apk/res/android"
app:defaultDuration="500"
xmlns:app="http://schemas.android.com/apk/res-auto">
<Transition
android:id="@+id/startToLeft3"
app:constraintSetEnd="@+id/unlike"
app:constraintSetStart="@+id/start">
<OnSwipe
app:dragDirection="dragLeft"
app:touchAnchorId="@id/cardOne"
app:touchAnchorSide="left"
app:touchRegionId="@id/cardOne" />
<KeyFrameSet>
<KeyPosition
app:framePosition="50"
app:keyPositionType="pathRelative"
app:motionTarget="@id/cardOne"
app:percentY="0.3" />
<KeyPosition
app:framePosition="50"
app:keyPositionType="pathRelative"
app:motionTarget="@id/topInterestPointName"
app:percentY="0.3" />
</KeyFrameSet>
</Transition>
<Transition
android:id="@+id/startToRight3"
app:constraintSetEnd="@+id/like"
app:constraintSetStart="@+id/start">
<OnSwipe
app:dragDirection="dragRight"
app:touchAnchorId="@id/cardOne"
app:touchAnchorSide="right"
app:touchRegionId="@id/cardOne" />
<KeyFrameSet>
<KeyPosition
app:framePosition="50"
app:keyPositionType="pathRelative"
app:motionTarget="@id/cardOne"
app:percentY="-0.3" />
<KeyPosition
app:framePosition="50"
app:keyPositionType="pathRelative"
app:motionTarget="@id/topInterestPointName"
app:percentY="-0.3" />
</KeyFrameSet>
</Transition>
...
这是片段中的转换侦听器:
matchingMotionLayout.setTransitionListener(object : TransitionAdapter() {
override fun onTransitionCompleted(motionLayout: MotionLayout, currentId: Int) {
when (currentId) {
R.id.offScreenUnlike -> {
if (vm.shouldResetScene) {
motionLayout.progress = 0f
motionLayout.setTransition(R.id.start, R.id.start)
}
vm.unlike()
}
R.id.offScreenLike -> {
if (vm.shouldResetScene) {
motionLayout.progress = 0f
motionLayout.setTransition(R.id.start, R.id.start)
}
vm.like()
}
R.id.start -> {
motionLayout.progress = 0f
motionLayout.setTransition(R.id.start, R.id.start)
}
}
super.onTransitionCompleted(motionLayout, currentId)
}
})
对我有用的解决方案: 因此,在连续 1 周尝试不同的方法后,我终于找到了有效的方法。
class ClickableMotionLayout @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : MotionLayout(context, attrs, defStyleAttr) {
override fun onInterceptTouchEvent(event: MotionEvent?): Boolean {
return event?.action == MotionEvent.ACTION_MOVE
}
}
cardOne.setOnTouchListener(imageSeekListener)
在 touchListener 中,我通过传递 touchListener 接收到的事件来调用 MotionLayout 的 onTouchEvent,当操作为 ACTION_DOWN 时,我返回 true。
private var imageSeekListener: View.OnTouchListener? = View.OnTouchListener { v, event ->
binding.matchingMotionLayout.onTouchEvent(event)
if (event.action == MotionEvent.ACTION_DOWN) {
return@OnTouchListener true
}
if (event.action == MotionEvent.ACTION_UP) {
when (getTouchSide(v, event)) {
TouchSide.LEFT -> vm.peekPreviousPhoto()
TouchSide.RIGHT -> vm.peekNextPhoto()
}
}
return@OnTouchListener false
}
现在我可以点击卡片来查看照片,然后滑动卡片以显示另一张卡片,而无需触发点击。希望它对某人有帮助。