I have an app, where I need to display multiple RecyclerView
s inside ConstraintLayout
inside NestedScrollView
inside SwipeRefreshLayout
.
All RecyclerView
s have LinearLayoutManager
with horizontal orientation.
So, my current layout tree looks like this:
<SwipeRefreshLayout>
<NestedScrollView>
<ConstraintLayout>
<RecyclerView></RecyclerView>
<RecyclerView></RecyclerView>
<RecyclerView></RecyclerView>
...
</ConstraintLayout>
</NestedScrollView>
</SwipeRefreshLayout>
What I'm trying to achieve is something similar to what Google Play app has on Home screen.
My problem is such, that RecyclerView
s are way too picky about what can be considered a horizontal swipe.
I tried to setNestedScrollingEnabled(false)
but to no avail.
Then I started to look into onTouch()
methods of everything above RecyclerView
s and I found, that ACTION_DOWN
of MotionEvent
does appear only if I scroll very slowly - anything, that can be considered a swipe/fling doesn't produce ACTION_DOWN
, only ACTION_MOVE
and ACTION_UP
.
Is there something I don't know about this construction? Does some view consume ACTION_DOWN
?
And side question - are there examples of recreating not only appearance of Google Play Home screen, but also a feel? Their horizontal lists are way more forgiving, when it comes to horizontal scroll.
EDIT: Added OnItemTouchListener
to all my RecyclerView
s. It intercepts ALL swipes/flings/scrolls correctly, but not all trigger OnSwipeListener. Here's code. Side note: OnSwipeListener is taken from this answer with slight addition of onScroll
method
public class MyOnItemTouchListener extends RecyclerView.SimpleOnItemTouchListener {
private GestureDetectorCompat mDetector;
private OnSwipeListener mListener = new OnSwipeListener() {
@Override public boolean onSwipe(Direction direction) {
Log.d("Tag", "OnItemListener direction=" + direction);
return super.onSwipe(direction);
}
};
public HomeOnItemTouchListener(Context context) {
mDetector = new GestureDetectorCompat(context, mListener);
}
@Override public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
Log.d("Tag", "OnItemListener intercept MotionEvent=" + e);
mDetector.onTouchEvent(e);
return super.onInterceptTouchEvent(rv, e);
}
@Override public void onTouchEvent(RecyclerView rv, MotionEvent e) {
Log.d("Tag", "OnItemListener onTouch MotionEvent=" + e);
mDetector.onTouchEvent(e);
super.onTouchEvent(rv, e);
}
}