Reputation: 1
I'm trying to implement nested RecyclerView
s with 3 layers. The 1st RecyclerView
(parent) view is set to scroll vertically. The 2nd RecyclerView
(child of the 1st) view is set to scroll horizontally. The 3rd RecyclerView
(child of the 2nd) view is also set to scroll horizontally.
To visualize:
-> RecyclerView
with vertical scroll
--> RecyclerView
with horizontal scroll
---> RecyclerView
with horizontal scroll
Now, the problem is I can't make the 3rd horizontal RecyclerView scroll horizontally. I think the problem is the device is prioritising the horizontal scroll of the 2nd RecyclerView
.
Can you help me solve this issue?
This is the snippet code for the layout of the 1st one with vertical scrolling:
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</android.support.v4.widget.NestedScrollView>
This is for the 2nd one with horizontal scrolling:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
This is for the last one with horizontal scrolling:
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
I already tried intercepting the touch with onIntercept...()
to cancel the scrolling of the 2nd RecyclerView
while the 3rd is being touched.
Upvotes: 0
Views: 604
Reputation: 1594
public class NestedScrollViewHome extends NestedScrollView {
@SuppressWarnings("unused")
private int slop;
@SuppressWarnings("unused")
private float mInitialMotionX;
@SuppressWarnings("unused")
private float mInitialMotionY;
public NestedScrollViewHome(Context context) {
super(context);
init(context);
}
private void init(Context context) {
ViewConfiguration config = ViewConfiguration.get(context);
slop = config.getScaledEdgeSlop();
}
public NestedScrollViewHome(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public NestedScrollViewHome(Context context, AttributeSet attrs,
int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
private float xDistance, yDistance, lastX, lastY;
@SuppressWarnings("unused")
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
final float x = ev.getX();
final float y = ev.getY();
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
xDistance = yDistance = 0f;
lastX = ev.getX();
lastY = ev.getY();
// This is very important line that fixes
computeScroll();
break;
case MotionEvent.ACTION_MOVE:
final float curX = ev.getX();
final float curY = ev.getY();
xDistance += Math.abs(curX - lastX);
yDistance += Math.abs(curY - lastY);
lastX = curX;
lastY = curY;
if (xDistance > yDistance) {
return false;
}
}
return super.onInterceptTouchEvent(ev);
}
public interface OnScrollChangedListener {
void onScrollChanged(NestedScrollView who, int l, int t, int oldl,
int oldt);
}
private OnScrollChangedListener mOnScrollChangedListener;
public void setOnScrollChangedListener(OnScrollChangedListener listener) {
mOnScrollChangedListener = listener;
}
@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
super.onScrollChanged(l, t, oldl, oldt);
if (mOnScrollChangedListener != null) {
mOnScrollChangedListener.onScrollChanged(this, l, t, oldl, oldt);
}
}
}
Upvotes: 0