Android MotionLayout:如何在特定视图上限制“OnSwipe”事件,而不是在整个屏幕上限制“OnSwipe”
我有一个带有以下“layoutDescription”场景文件的motionlayoutAndroid MotionLayout:如何在特定视图上限制“OnSwipe”事件,而不是在整个屏幕上限制“OnSwipe”,android,android-animation,android-motionlayout,Android,Android Animation,Android Motionlayout,我有一个带有以下“layoutDescription”场景文件的motionlayout <Transition motion:constraintSetStart="@+id/start" motion:constraintSetEnd="@+id/end" motion:duration="1000"> <OnSwipe motion:touchAnchorId="@+id/button" motio
<Transition
motion:constraintSetStart="@+id/start"
motion:constraintSetEnd="@+id/end"
motion:duration="1000">
<OnSwipe
motion:touchAnchorId="@+id/button"
motion:touchAnchorSide="left"
motion:dragDirection="dragLeft" />
</Transition>
<ConstraintSet android:id="@+id/start">
<!-- ConstraintSet for starting -->
</ConstraintSet>
<ConstraintSet android:id="@+id/end">
<!-- ConstraintSet for end -->
</ConstraintSet>
我从这里期望的是,如果用户向左拖动“按钮”,那么它应该执行转换,但实际发生的是,当用户从屏幕中的任何位置向左拖动时,将执行此转换
如何仅在拖动指定视图时限制动画工作
我正在使用constraintlayout:2.0.0-beta2更新的答案:使用constraintlayout 2.0.0 alpha-5,您可以简单地使用 应用程序:touchRegionId 因为同样的行为,在你的办公室里。也可以使用“app:targetId”进行OnClick使用 谢谢@RuslanLeshchenko 原始答复: 最后,我通过扩展MotionLayout和覆盖onTouchEvent将事件转发到所需的视图来实现这一点 通过扩展MotionLayout创建自定义布局
class SingleViewTouchableMotionLayout(context: Context, attributeSet: AttributeSet? = null) : MotionLayout(context, attributeSet) {
private var viewToDetectTouch1 :View? = null
private var viewToDetectTouchRes :Int = -1
private val viewRect = Rect()
private var touchStarted = false
init {
setTransitionListener(object : MotionLayout.TransitionListener {
override fun onTransitionTrigger(p0: MotionLayout?, p1: Int, p2: Boolean, p3: Float) {
}
override fun onTransitionStarted(p0: MotionLayout?, p1: Int, p2: Int) {
}
override fun onTransitionChange(p0: MotionLayout, p1: Int, p2: Int, p3: Float) {
}
override fun onTransitionCompleted(p0: MotionLayout, p1: Int) {
touchStarted = false
}
})
context.theme.obtainStyledAttributes(
attributeSet,
R.styleable.SingleViewTouchableMotionLayout,
0, 0).apply {
try {
viewToDetectTouchRes = getResourceId(
R.styleable.SingleViewTouchableMotionLayout_viewToDetectTouch, 0)
} finally {
recycle()
}
}
}
override fun onAttachedToWindow() {
super.onAttachedToWindow()
viewToDetectTouch1 = (parent as View).findViewById<View>(viewToDetectTouchRes)
}
override fun onTouchEvent(event: MotionEvent): Boolean {
when (event.actionMasked) {
MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
touchStarted = false
return super.onTouchEvent(event)
}
}
if (!touchStarted) {
viewToDetectTouch1?.getHitRect(viewRect)
touchStarted = viewRect.contains(event.x.toInt(), event.y.toInt())
}
return touchStarted && super.onTouchEvent(event)
}
}
并添加自定义属性,该属性将用于声明接收事件以触发转换/动画的视图。
将这些可设置样式的文件添加到res文件夹res/values/attrs.xml中的attrs.xml中
更新答案:使用ConstraintLayout 2.0.0 alpha-5,您可以简单地使用 应用程序:touchRegionId 因为同样的行为,在你的办公室里。也可以使用“app:targetId”进行OnClick使用 谢谢@RuslanLeshchenko 原始答复: 最后,我通过扩展MotionLayout和覆盖onTouchEvent将事件转发到所需的视图来实现这一点 通过扩展MotionLayout创建自定义布局
class SingleViewTouchableMotionLayout(context: Context, attributeSet: AttributeSet? = null) : MotionLayout(context, attributeSet) {
private var viewToDetectTouch1 :View? = null
private var viewToDetectTouchRes :Int = -1
private val viewRect = Rect()
private var touchStarted = false
init {
setTransitionListener(object : MotionLayout.TransitionListener {
override fun onTransitionTrigger(p0: MotionLayout?, p1: Int, p2: Boolean, p3: Float) {
}
override fun onTransitionStarted(p0: MotionLayout?, p1: Int, p2: Int) {
}
override fun onTransitionChange(p0: MotionLayout, p1: Int, p2: Int, p3: Float) {
}
override fun onTransitionCompleted(p0: MotionLayout, p1: Int) {
touchStarted = false
}
})
context.theme.obtainStyledAttributes(
attributeSet,
R.styleable.SingleViewTouchableMotionLayout,
0, 0).apply {
try {
viewToDetectTouchRes = getResourceId(
R.styleable.SingleViewTouchableMotionLayout_viewToDetectTouch, 0)
} finally {
recycle()
}
}
}
override fun onAttachedToWindow() {
super.onAttachedToWindow()
viewToDetectTouch1 = (parent as View).findViewById<View>(viewToDetectTouchRes)
}
override fun onTouchEvent(event: MotionEvent): Boolean {
when (event.actionMasked) {
MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
touchStarted = false
return super.onTouchEvent(event)
}
}
if (!touchStarted) {
viewToDetectTouch1?.getHitRect(viewRect)
touchStarted = viewRect.contains(event.x.toInt(), event.y.toInt())
}
return touchStarted && super.onTouchEvent(event)
}
}
并添加自定义属性,该属性将用于声明接收事件以触发转换/动画的视图。
将这些可设置样式的文件添加到res文件夹res/values/attrs.xml中的attrs.xml中
实际上,对于onSwipe,您可以对OnClick使用touchRegionId和targetId实际上对于onSwipe,您可以对OnClick使用touchRegionId和targetId运动布局onSwipe适用于整个屏幕。如果你想完成这项任务,可以参考Thank you@SurajGhadge。你的宝贵意见让我找到了解决办法!欢迎光临,它对您的帮助真是太好了。MotionLayout OnSwipe适用于整个屏幕。如果你想完成这项任务,可以参考Thank you@SurajGhadge。你的宝贵意见让我找到了解决办法!欢迎你,这对你很有帮助。哈哈,我的错!这很有效。它可以从alpha 5版本获得。谢谢,我想知道OnClick和OnSwipe是否都适用于相同的视图,或者是一个bug?哈哈,我的错!这很有效。它可以从alpha 5版本获得。谢谢,我想知道OnClick和OnSwipe是否都适用于相同的视图,还是一个bug?