mue*_*flo 4 android onclicklistener android-constraintlayout android-motionlayout
我正在使用带有场景 xml 的 MotionLayout:
<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>
Run Code Online (Sandbox Code Playgroud)
2ConstraintSets只引用了 2 个视图 ID:v_notifications_container和v_top_sheet。
在我的活动中,我想将一个普通的 ClickListener 设置为这个 MotionLayout 中的其他视图之一:
iv_notification_status.setOnClickListener { Timber.d("Hello") }
Run Code Online (Sandbox Code Playgroud)
执行此行,但从未触发 ClickListener。我搜索了其他帖子,但其中大多数都涉及在与motion:touchAnchorId. 这不是这里的情况。ClickListener 设置为在 MotionLayout 设置中未曾提及的视图。如果我删除该app:layoutDescription属性,则单击有效。
我也尝试使用setOnTouchListener,但它也从未被调用过。
如何在 MotionLayout 中设置单击侦听器?
在这篇优秀的中等文章的帮助下,我发现 MotionLayout 正在拦截点击事件,即使运动场景只包含一个 OnSwipe 转换。
所以我写了一个定制的 MotionLayout 来只处理ACTION_MOVE和传递视图树下的所有其他触摸事件。奇迹般有效:
/**
* 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
}
}
Run Code Online (Sandbox Code Playgroud)
小智 1
对 @TimonNetherlands 代码的小修改也适用于 Pixel4
class ClickableMotionLayout: MotionLayout {
private var mStartTime: Long = 0
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_DOWN ) {
mStartTime = event.eventTime;
}
if ((event?.eventTime?.minus(mStartTime)!! >= ViewConfiguration.getTapTimeout()) && event.action == MotionEvent.ACTION_MOVE) {
return super.onInterceptTouchEvent(event)
}
return false;
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1661 次 |
| 最近记录: |