ScrollView中的多个RecyclerViews不能一直滚动

时间:2019-09-04 20:38:36

标签: android android-recyclerview

我有三个水平滚动回收站视图,这些视图在垂直方向上对于应用程序屏幕而言太大。为了解决这个问题,我将它们嵌套在NestedScrollView内,但是垂直滚动并没有一直到最后一个回收站视图的底部。

这是视图将滚动到的最大范围:

multiple_recycler_views

这是我的配置:

容器视图:

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <androidx.core.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:fillViewport="true">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <include
                android:id="@+id/recyclerTop"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                layout="@layout/recycler_with_filters"/>

            <include
                android:id="@+id/recyclerMiddle"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                layout="@layout/recycler_with_filters"/>

            <include
                android:id="@+id/recyclerBottom"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                layout="@layout/recycler_with_filters"/>

        </LinearLayout>

    </androidx.core.widget.NestedScrollView>

</LinearLayout>

包含的布局:

<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/header"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginStart="10dp"
        android:layout_marginLeft="10dp"
        android:layout_marginTop="10dp"
        android:text="Test!"
        android:textColor="@color/colorPrimaryDark"
        android:textSize="24sp"
        app:fontFamily="@font/didot"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <LinearLayout
        android:id="@+id/filters"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_marginLeft="10dp"
        android:layout_marginStart="10dp"
        android:layout_marginTop="10dp"
        android:orientation="horizontal"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toBottomOf="@id/header">

        <Button
            android:id="@+id/filter1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:background="@drawable/btn_filter_inactive"
            android:textColor="@color/colorPrimaryDark"
            android:text="filter1" />

        <Button
            android:id="@+id/filter2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:background="@drawable/btn_filter_inactive"
            android:textColor="@color/colorPrimaryDark"
            android:text="filter2" />

        <Button
            android:id="@+id/filter3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:background="@drawable/btn_filter_inactive"
            android:textColor="@color/colorPrimaryDark"
            android:text="filter3" />

        <Button
            android:id="@+id/filter4"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:background="@drawable/btn_filter_inactive"
            android:textColor="@color/colorPrimaryDark"
            android:text="filter4" />

    </LinearLayout>

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recycler_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:layout_marginStart="10dp"
        android:layout_marginTop="10dp"
        android:scrollbars="vertical"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toBottomOf="@id/filters" />

</androidx.constraintlayout.widget.ConstraintLayout>

控制器:

公共类TestRecyclerFragment扩展了片段{

public static TestRecyclerFragment newInstance() {
    return new TestRecyclerFragment();
}

private RecyclerView mRecyclerViewTop;
private RecyclerView mRecyclerViewMiddle;
private RecyclerView mRecyclerViewBottom;
private RecyclerView.Adapter mAdapterTop;
private RecyclerView.Adapter mAdapterMiddle;
private RecyclerView.Adapter mAdapterBottom;


private Business[] mBusinesses = {new Business("The Tavern", 0), new Business("The Tavern1", 0), new Business("The Tavern2", 0), new Business("The Tavern3", 0), new Business("The Tavern4", 0), new Business("The Tavern5", 0), new Business("The Tavern6", 1), new Business("The Tavern7", 1), new Business("The Tavern8", 1), new Business("The Tavern9", 1), new Business("The Tavern10", 1), new Business("The Tavern11", 1)};

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    View v = inflater.inflate(R.layout.fragment_test_recycler, container, false);

    View recycleWithFilterTop = v.findViewById(R.id.recyclerTop);
    mRecyclerViewTop = recycleWithFilterTop.findViewById(R.id.recycler_view);

    View recycleWithFilterMiddle = v.findViewById(R.id.recyclerMiddle); 
    mRecyclerViewMiddle = recycleWithFilterMiddle.findViewById(R.id.recycler_view);

    View recycleWithFilterBottom = v.findViewById(R.id.recyclerBottom); 
    mRecyclerViewBottom = recycleWithFilterBottom.findViewById(R.id.recycler_view); 

    mRecyclerViewTop.setHasFixedSize(true);
    mRecyclerViewMiddle.setHasFixedSize(true);
    mRecyclerViewBottom.setHasFixedSize(true);

    RecyclerView.LayoutManager layoutManagerTop = new LinearLayoutManager(getActivity(), LinearLayoutManager.HORIZONTAL, false);
    mRecyclerViewTop.setLayoutManager(layoutManagerTop);

    RecyclerView.LayoutManager layoutManagerMiddle = new LinearLayoutManager(getActivity(), LinearLayoutManager.HORIZONTAL, false);
    mRecyclerViewMiddle.setLayoutManager(layoutManagerMiddle);

    RecyclerView.LayoutManager layoutManagerBottom = new LinearLayoutManager(getActivity(), LinearLayoutManager.HORIZONTAL, false);
    mRecyclerViewBottom.setLayoutManager(layoutManagerBottom);

    mAdapterTop = new TestRecyclerFragment.TestAdapter(mBusinesses);
    mRecyclerViewTop.setAdapter(mAdapterTop);

    mAdapterMiddle = new TestRecyclerFragment.TestAdapter(mBusinesses);
    mRecyclerViewMiddle.setAdapter(mAdapterMiddle);

    mAdapterBottom = new TestRecyclerFragment.TestAdapter(mBusinesses);
    mRecyclerViewBottom.setAdapter(mAdapterBottom);

    return v;
}

public class TestAdapter extends RecyclerView.Adapter<TestAdapter.MyViewHolder> {
    private Business[] businesses;

    public class MyViewHolder extends RecyclerView.ViewHolder {
        private TextView mBusinessName;

        public MyViewHolder(View v) {
            super(v);
            mBusinessName = itemView.findViewById(R.id.businessName);
        }
    }

    public TestAdapter(Business[] myDataset) {
        mBusinesses = myDataset;
    }

    @Override
    public TestAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent,
                                                       int viewType) {
        View v = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.view_holder_businesses, parent, false);

        MyViewHolder vh = new MyViewHolder(v);
        return vh;
    }

    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {
        holder.mBusinessName.setText(mBusinesses[position].getName());
    }

    // Return the size of your dataset (invoked by the layout manager)
    @Override
    public int getItemCount() {
        return mBusinesses.length;
    }

    @Override
    public int getItemViewType(int position) {
        return mBusinesses[position].getViewType();
    }
}

}

* Edit:我认为问题与滚动有关,因为它不知道在绘制视图时视图的大小。我已经尝试过硬编码包含中的高度,例如:

<include
    android:id="@+id/recyclerTop"
    android:layout_width="match_parent"
    android:layout_height="400dp"
    layout="@layout/recycler_with_filters"/>

但是,这弄乱了视图。

* Edit2:我已经尝试过在该主题的其他问题中倡导的许多解决方案,包括将设置nestedScrollingEnabling设置为false。这些解决方案在我的实例中不起作用。我不确定这是否与我的配置有所不同,还是使用的是NestedScrollView api的较新版本。

3 个答案:

答案 0 :(得分:0)

通过向底部回收者视图的布局参数添加动态高度,我能够使滚动视图滚动到底部:

RecyclerView.LayoutManager layoutManagerBottom = new LinearLayoutManager(getActivity(), LinearLayoutManager.HORIZONTAL, false);
mRecyclerViewBottom.setLayoutManager(layoutManagerBottom);

final float scale = getContext().getResources().getDisplayMetrics().density;
int pixels = (int) (550 * scale + 0.5f);
mRecyclerViewBottom.getLayoutParams().height = pixels;

答案 1 :(得分:0)

考虑到市场上不同的屏幕分辨率,添加静态高度不是正确的解决方案。如果您想在Recyclerviews中作为一个整体进行多个NestedScrollView滚动,则应考虑将android:nestedScrollingEnabled="false"添加到Recyclerview

<android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:padding="@dimen/margin_activity_horizontal">

        <android.support.v7.widget.RecyclerView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layoutManager="LinearLayoutManager"
            android:nestedScrollingEnabled="false"/>

        <android.support.v7.widget.RecyclerView
            android:layout_below="@+id/recycler_view_departments"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layoutManager="LinearLayoutManager"
            android:nestedScrollingEnabled="false"/>

    </RelativeLayout>
</android.support.v4.widget.NestedScrollView>

答案 2 :(得分:0)

我已经测试了您的代码,这对我来说很正常,只是我在TestRecyclerFragment onCreateView方法中添加了以下三行代码

    mRecyclerViewTop.setNestedScrollingEnabled(false);
    mRecyclerViewMiddle.setNestedScrollingEnabled(false);
    mRecyclerViewBottom.setNestedScrollingEnabled(false);

您可以看到有效的演示https://www.dropbox.com/s/zmfmcdjw58cto4q/device-2019-09-05-115921.mp4?dl=0