Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/206.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android MotionLayout:如何在特定视图上限制“OnSwipe”事件,而不是在整个屏幕上限制“OnSwipe”_Android_Android Animation_Android Motionlayout - Fatal编程技术网

Android MotionLayout:如何在特定视图上限制“OnSwipe”事件,而不是在整个屏幕上限制“OnSwipe”

Android 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

我有一个带有以下“layoutDescription”场景文件的motionlayout

    <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?