代码之家  ›  专栏  ›  技术社区  ›  Braden Holt

ScrollView中的多个RecyclerView不会一直滚动

  •  0
  • Braden Holt  · 技术社区  · 5 年前

    我有三个水平滚动回收器视图,这些视图对于应用程序屏幕来说太大了。为了解决这个问题,我将它们嵌套在一个嵌套的scroll视图中,但是垂直滚动并没有一直到最后一个回收器视图的底部。

    这是视图将滚动的最远距离:

    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();
        }
    }
    

    }

    *编辑:我认为这个问题与画卷有关,因为它不知道在绘制视图时视图会有多大。我试着用下面这样的方式来编码include中的高度:

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

    不过,那会把景色弄糟。

    *edit2:我已经尝试了很多其他问题的解决方案,包括设置 nestedScrollingEnabling false . 这些解决方案在我的情况下不起作用。我不确定这是我的配置有什么不同,还是我正在使用一个新版本的nestedscrollview api。

    0 回复  |  直到 5 年前
        1
  •  0
  •   Farid    5 年前

    考虑到市场上不同的屏幕分辨率,增加静态高度并不是一个合适的解决方案。如果你想有多个 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
  •   Braden Holt    5 年前

    通过在底部回收器视图的布局参数中添加静态高度,我可以使滚动视图滚动到底部:

    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;
    
        3
  •  0
  •   Kailash Chouhan    5 年前

    我已经测试了您的代码,它在我这边运行得很好,只是在testRecyclerFragment onCreateView方法中添加了以下3行代码

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

    你可以看到工作演示 https://www.dropbox.com/s/zmfmcdjw58cto4q/device-2019-09-05-115921.mp4?dl=0