Android SDK中的非Scroll RecyclerView滚动问题23

时间:2015-11-24 09:22:34

标签: android android-recyclerview android-6.0-marshmallow

我正在RecyclerView内部实施ScrollView。为了在整个页面上只有一个滚动行为,我实现了NonScrollRecyclerView版本。实施如下:

public class NonScrollRecyclerView extends RecyclerView {
    public NonScrollRecyclerView(Context context) { super(context); }

    public NonScrollRecyclerView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public NonScrollRecyclerView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev){

        if(ev.getAction() == MotionEvent.ACTION_MOVE)
            return true;

        return super.dispatchTouchEvent(ev);
    }
}

我将构建和目标设置更新到SDK 23后,无法滚动包含NonScrollRecyclerView的页面。具体问题是页面滚动正常,直到我到达回收站视图部分,一旦我滚动到此视图,我无法向上或向下滚动。

我不想在SDK 22及以下版本中遇到此问题

我的xml如下:

XML @layout/rv包含回收站视图

<ScrollView 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="@color/background_gray">

 <LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/background_gray"
    android:orientation="vertical">

    <include
        layout="@layout/row_mall_header"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/cv_mall_header"
        android:layout_marginTop="8dp"/>

    <include
        layout="@layout/row_mall_shops"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/cv_mall_shops"
        android:layout_marginTop="8dp"/>

    <include
        layout="@layout/row_mall_coupons"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/cv_mall_coupons"
        android:layout_marginTop="8dp"/>

    <include
        layout="@layout/rv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/cv_mall_feeds"
        android:layout_marginTop="8dp"/>

  </LinearLayout>
</ScrollView>

XML - @ layout / rv

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="vertical" android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:background="@color/background_gray"
  android:id="@+id/ll_mall_feeds">

 <RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/white"
    android:paddingTop="6dp"
    android:paddingBottom="6dp">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/tv_feedcount"
        android:textColor="@color/semi_theme_blue"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_marginLeft="12dp"
        android:layout_centerVertical="true" />

 </RelativeLayout>

 <com.project.ui.NonScrollRecyclerView
     android:id="@+id/nrv"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:divider="@android:color/transparent"
     android:listSelector="@android:color/transparent" />

</LinearLayout>

2 个答案:

答案 0 :(得分:2)

在ScrollView中不建议使用RecyclerView和ListView,因为在渲染ScrollView时不会计算元素高度。这意味着,在显示ScrollView时以及稍后当RecyclerView收到有关数据更改的通知时(例如初始化适配器时),可能不会填充适配器,因此无法重新计算元素高度。

这真的是一种痛苦,因为你必须尝试计算元素高度并且它永远不准确,所以当你在ScrollView中显示ListView或RecyclerView时会有差异。可以检查有关如何计算元素高度的一些示例herehere

我的建议是将您的RecyclerView转换为LinearLayout并以编程方式添加元素,以便模拟ListView或RecyclerView行为:

LinearLayout layout = (LinearLayout) rootView.findViewById(R.id.files);
layout.removeAllViews();

for (int i = 0; i < fileAdapter.getCount(); i++) {
    final View item = fileAdapter.getView(i, null, null);
item.setClickable(true);

    item.setId(i);

    item.setOnClickListener(new View.OnClickListener() {
        @Override
            public void onClick(View v) {

                fileContentRowPosition = v.getId();

        # Your click action here


    }
});


layout.addView(item);

}

这是带有文件定义的XML:

<ScrollView
    android:id="@+id/scrollView1"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

...

    <LinearLayout
        android:id="@+id/files"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="5dp"
        android:layout_marginRight="5dp"
        android:orientation="vertical">
    </LinearLayout>


</ScrollView>

可以检查整个Java代码here和整个布局here

另一方面,如果您仍想继续执行您的问题,并且可以查看有关Handling Scrollable Controls in Scrollview

的文章。

致以最诚挚的问候,

答案 1 :(得分:1)

对于整个页面中只有一个滚动,您可以使用 NestedScrollView 而不是 ScrollView 并设置recyclerView.setNestedScrollingEnabled(false);