MotionLayout可防止在所有视图上使用ClickListener [英] MotionLayout prevents ClickListener on all Views

查看:62
本文介绍了MotionLayout可防止在所有视图上使用ClickListener的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在将MotionLayout与scene-xml一起使用:

I am using a MotionLayout with a scene-xml:

<Transition
    motion:constraintSetStart="@+id/start"
    motion:constraintSetEnd="@+id/end"
    >
    <OnSwipe
        motion:touchAnchorId="@+id/v_top_sheet"
        motion:touchRegionId="@+id/v_top_sheet_touch_region"
        motion:touchAnchorSide="bottom"
        motion:dragDirection="dragDown" />
</Transition>

这两个 ConstraintSets 仅引用了两个View ID: v_notifications_container v_top_sheet .

The 2 ConstraintSets are referencing only 2 View IDs: v_notifications_container and v_top_sheet.

在我的活动"中,我想为该MotionLayout中的其他视图之一设置普通的ClickListener:

In my Activity I want to set a normal ClickListener to one of the other Views in this MotionLayout:

iv_notification_status.setOnClickListener { Timber.d("Hello") }

该行已执行,但ClickListener从未触发.我搜索了其他帖子,但是大多数帖子都涉及在同一视图(即 motion:touchAnchorId )上设置ClickListener的问题.这里不是这种情况.ClickListener设置为一个在MotionLayout设置中未曾提及的视图.如果删除 app:layoutDescription 属性,则单击有效.

This line is executed, but the ClickListener is never triggered. I searched other posts, but most of them deal with setting a ClickListener on the same View that is the motion:touchAnchorId. This is not the case here. The ClickListener is set to a View that is not once mentioned in the MotionLayout setup. If I remove the app:layoutDescription attribute, the click works.

我也尝试使用 setOnTouchListener ,但也从未使用过.

I also tried to use setOnTouchListener, but it is also never called.

如何在MotionLayout中设置点击侦听器?

推荐答案

借助

With the help of this great medium article I figured out that MotionLayout is intercepting click events even though the motion scene only contains an OnSwipe transition.

因此,我编写了一个自定义的MotionLayout,以仅处理 ACTION_MOVE 并将所有其他触摸事件传递到视图树.像魅力一样工作:

So I wrote a customized MotionLayout to only handle ACTION_MOVE and pass all other touch events down the View tree. Works like a charm:

/**
 * MotionLayout will intercept all touch events and take control over them.
 * That means that View on top of MotionLayout (i.e. children of MotionLayout) will not
 * receive touch events.
 *
 * If the motion scene uses only a onSwipe transition, all click events are intercepted nevertheless.
 * This is why we override onInterceptTouchEvent in this class and only let swipe actions be handled
 * by MotionLayout. All other actions are passed down the View tree so that possible ClickListener can
 * receive the touch/click events.
 */
class ClickableMotionLayout: MotionLayout {

    constructor(context: Context) : super(context)

    constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)

    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr)

    override fun onInterceptTouchEvent(event: MotionEvent?): Boolean {
        if (event?.action == MotionEvent.ACTION_MOVE) {
            return super.onInterceptTouchEvent(event)
        }
        return false
    }

}

这篇关于MotionLayout可防止在所有视图上使用ClickListener的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆