tcfarmer2
tcfarmer2

Reputation: 11

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!

Upvotes: 1

Views: 431

Answers (2)

paul feng
paul feng

Reputation: 11

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)
}

Upvotes: 1

hoford
hoford

Reputation: 5323

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

Upvotes: 0

Related Questions