这个问题对我来说似乎很有趣。所以我尝试实现,这就是我实现的(你也可以看到video here),非常顺利。
所以你可以试试这样的:
像这样定义CustomLinearLayoutManager 扩展LinearLayoutManager:
public class CustomLinearLayoutManager extends LinearLayoutManager {
public CustomLinearLayoutManager(Context context, int orientation, boolean reverseLayout) {
super(context, orientation, reverseLayout);
}
@Override
public boolean canScrollVertically() {
return false;
}
}
并将此 CustomLinearLayoutManager 设置为您的父级 RecyclerView。
RecyclerView parentRecyclerView = (RecyclerView)findViewById(R.id.parent_rv);
CustomLinearLayoutManager customLayoutManager = new CustomLinearLayoutManager(this, LinearLayoutManager.HORIZONTAL,false);
parentRecyclerView.setLayoutManager(customLayoutManager);
parentRecyclerView.setAdapter(new ParentAdapter(this)); // some adapter
现在对于子 RecyclerView,定义自定义 CustomGridLayoutManager 扩展 GridLayoutManager:
public class CustomGridLayoutManager extends GridLayoutManager {
public CustomGridLayoutManager(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
public CustomGridLayoutManager(Context context, int spanCount) {
super(context, spanCount);
}
public CustomGridLayoutManager(Context context, int spanCount, int orientation, boolean reverseLayout) {
super(context, spanCount, orientation, reverseLayout);
}
@Override
public boolean canScrollHorizontally() {
return false;
}
}
并将其设置为layoutManger 给孩子RecyclerView:
childRecyclerView = (RecyclerView)itemView.findViewById(R.id.child_rv);
childRecyclerView.setLayoutManager(new CustomGridLayoutManager(context, 3));
childRecyclerView.setAdapter(new ChildAdapter()); // some adapter
所以基本上父RecyclerView 只听水平滚动和孩子RecyclerView 只听垂直滚动。
除此之外,如果您还想处理对角滑动(几乎不偏向垂直或水平),您可以在 parent RecylerView 中包含一个手势监听器。
public class ParentRecyclerView extends RecyclerView {
private GestureDetector mGestureDetector;
public ParentRecyclerView(Context context) {
super(context);
mGestureDetector = new GestureDetector(this.getContext(), new XScrollDetector());
// do the same in other constructors
}
// and override onInterceptTouchEvent
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return super.onInterceptTouchEvent(ev) && mGestureDetector.onTouchEvent(ev);
}
}
XScrollDetector 在哪里
class XScrollDetector extends GestureDetector.SimpleOnGestureListener {
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
return Math.abs(distanceY) < Math.abs(distanceX);
}
}
因此ParentRecyclerView 要求子视图(在我们的例子中为 VerticalRecyclerView)来处理滚动事件。如果子视图处理,则父视图不执行任何其他操作,父视图最终会处理滚动。