'ClickListener added to view of MotionLayout prevents layout from responding to events
I have ImageViews in a MotionLayout to animate moving the ImageView across the screen. I want to also add a ClickListener to the ImageView so that there can be functionality when the ImageView is simply clicked/tapped instead of moved.
I followed the advice here to write a custom MotionLayout which only handles ACTION_MOVE but after adding the ClickListener to the ImageView in onCreate() only the ClickListener code would run and the MotionLayout would not respond. I've also tried overriding onTouchEvent() in a custom ImageView but that hasn't worked.
Inside Custom MotionLayout
<FrameLayout
android:id="@+id/bottomCard"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TapImageView
android:id="@+id/bottom"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitXY" />
</FrameLayout>
<FrameLayout
android:id="@+id/topCard"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TapImageView
android:id="@+id/top"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitXY" />
</FrameLayout>
Inside Custom ImageView
override fun onTouchEvent(event: MotionEvent?): Boolean {
when (event?.action) {
MotionEvent.ACTION_UP -> {
super.onTouchEvent(event)
Toast.makeText(context, "Works", Toast.LENGTH_LONG)
.show()
return false
}
}
return super.onTouchEvent(event)
}
I've also tried in activity onCreate()
binding.topCard.setOnClickListener {
Toast.makeText(applicationContext, "Works", Toast.LENGTH_LONG)
.show()
}
Thanks for your attention!
Solution 1:[1]
If you have your own Click listener you need to launch the transition from it. If the button is doing more than just animation. You will probably want to make some decisions on the animation. Remove the <OnClick .../> from the motionScene and add motionLayout.transitionToState(R.id.mystate); to your click handler
Solution 2:[2]
obviously, when MotionEvent is draging, it shouldn't allow children view to consume the event, so. i intercept the motionevent as underlying code . it works.
private var touchDownX = 0f
private var touchDownY = 0f
private var mScrolling = false
private val touchSlop = ViewConfiguration.get(context).scaledTouchSlop
override fun onInterceptTouchEvent(event: MotionEvent): Boolean {
when (event.action) {
MotionEvent.ACTION_DOWN -> {
touchDownX = event.x
touchDownY = event.y
mScrolling = false
}
MotionEvent.ACTION_MOVE -> mScrolling = abs(touchDownY - event.y) >= touchSlop
MotionEvent.ACTION_UP -> mScrolling = false
}
return if (mScrolling) true else super.onInterceptTouchEvent(event)
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | hoford |
| Solution 2 |
