I am running into an issue using MotionLayout
where a user cannot swipe up/down if they start their swipe on a clickable item. I want the user to be able to swipe over any part of the screen, and the swiping transition is triggered.
Basically, the behavior will be very similar to what is currently on the Yelp app for Android. Swiping up anywhere on the screen moves the search bar to the top of the screen. See this video of the swiping behavior.
My code for the transition looks something like this:
<Transition
app:constraintSetStart="@id/start"
app:constraintSetEnd="@id/end"
>
<OnSwipe
app:dragDirection="dragUp"
app:onTouchUp="decelerate"
/>
</Transition>
My code for the MotionLayout
looks something like this:
<androidx.constraintlayout.motion.widget.MotionLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layoutDescription="@xml/motion_scene">
>
<!-- other views -->
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/title"
android:textColor="@color/black"
android:textSize="14sp"
android:lineSpacingExtra="7sp"
android:fontFamily="@font/avenir"
android:layout_marginBottom="16dp"
/>
<GridView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:numColumns="2"
android:verticalSpacing="8dp"
android:horizontalSpacing="12dp"
android:stretchMode="columnWidth"
tools:listitem="@layout/griditem" <!-- This layout file contains a single <Button/> -->
/>
</LinearLayout>
</androidx.constraintlayout.motion.widget.MotionLayout>
Here are all of the things I have tried and couldn't get to work:
onInterceptTouchEvent
in the ViewGroup
parent of the clickable view (Just returning true here will result in the swiping behavior I want, but then the children views that should be clickable no longer are.)override fun onInterceptTouchEvent(ev: MotionEvent?): Boolean {
if (ev?.action == MotionEvent.ACTION_DOWN) {
onTouchEvent(ev)
return false
}
return true
}
onTouchEvent
in the clickable child viewoverride fun onTouchEvent(event: MotionEvent?): Boolean {
if (event?.action == MotionEvent.ACTION_DOWN) {
super.onTouchEvent(event)
return false
}
return super.onTouchEvent(event)
}
onInterceptTouchEvent
in the MotionLayout
override fun onInterceptTouchEvent(event: MotionEvent?): Boolean {
if (event?.action == MotionEvent.ACTION_MOVE) {
return super.onInterceptTouchEvent(event)
}
return false
}
I have looked at all of these StackOverflow posts (and more but these are the most relevant):
Any ideas as to what I could do here to be able to both swipe and click on items?
I got it working. Two things here that helped:
app:touchAnchorId
to the id of the RecyclerView.setTransition
to reset the transition back to the OnSwipe transition when appropriate.I hope that helps someone who runs into this problem.