两个嵌套的RecyclerViews的滚动行为

时间:2017-12-05 10:34:09

标签: android android-recyclerview

我有两个嵌套RecyclerView。其中一个管理垂直滑动,其中一个处理水平滑动。我面临的问题是,水平RecyclerView的滚动有时不会按预期运行。有时它不会识别水平滑动,只会进行垂直滑动。要进行水平滑动,必须在水平方向上绘制一条真正的直线。几度关闭将被识别为垂直滑动。是否有任何可以调整的参数,以使用户体验更好?

外部布局:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/white"
android:gravity="center">

<ProgressBar
    android:id="@+id/pb_new_home"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerInParent="true" />

<android.support.v7.widget.RecyclerView
    android:id="@+id/rv_modules"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:clipToPadding="false"
    android:nestedScrollingEnabled="false"
    android:paddingBottom="@dimen/newhome_recyclerview_paddingbottom" />
</RelativeLayout>

内部布局:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
style="@style/NewHomeModuleContainer">

<TextView
    android:id="@+id/tv_module_title"
    style="@style/NewHomeModuleTitle" />

<android.support.v7.widget.RecyclerView
    android:id="@+id/rv_horizontal_recycler"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_above="@+id/tv_show_more"
    android:layout_below="@id/tv_module_title"
    android:layout_marginBottom="-8dp"
    android:clipToPadding="false"
    android:paddingEnd="28dp"
    android:paddingRight="28dp" />

</RelativeLayout>

1 个答案:

答案 0 :(得分:0)

您需要创建一个自定义的RecyclerView,然后覆盖外部RecyclerView的onInterceptTouchEvent拦截触摸事件

boolean moveInnerRv;
private float startY;

@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
    float currentY = -1;
    switch(ev.getAction()){
        case MotionEvent.ACTION_DOWN:
            startY = ev.getRawY();
            break;

        case MotionEvent.ACTION_MOVE:
            currentY = ev.getRawY();
            break;

        case MotionEvent.ACTION_CANCEL:
        case MotionEvent.ACTION_UP:

            break;

        default:
            break;
    }
    // if move distance over 100, pass touch to inner RecyclerView
    moveInnerRv = !((currentY - startY) > 100);

    return moveInnerRv;
}