代码之家  ›  专栏  ›  技术社区  ›  Tom11

如何在一个布局中实现多个recyclerviews?

  •  5
  • Tom11  · 技术社区  · 8 年前

    我想创建一个窗格,其中有两个 RecyclerView s(比如说“MyItems”、“AllItems”)。我创造了垂直 LinearLayout ,其中有 TextView 作为头衔和 回收视图 .像这样:

    enter image description here

     <LinearLayout ... >
    
        <TextView
            android:text="My Items"
            ... />
    
        <android.support.v7.widget.RecyclerView
            android:id="@+id/my_items"
            ... />
    
        <TextView
            android:text="All Items"
            ... />
    
        <android.support.v7.widget.RecyclerView
            android:id="@+id/all_items"
            ... />
    
    </LinearLayout>
    

    然而,使用这种方法,只有recyclerViews是可独立滚动的,但我需要整个布局是可滚动的(所以它首先滚动第一部分,然后滚动第二部分)。我试着把它包起来 ScrollView NestedScrollView ,但最接近的是滚动 没有平滑的动画 .

    我的问题是,这种方法有效吗?如果有效,有没有办法添加平滑滚动 嵌套滚动视图 ? 或者我应该使用另一种方法来实现这一点,例如创建 ListView 包含两个项目,布局包含 文本框 回收视图 ?

    列表视图

    • 清单项目1

      • 标题1
      • 回收视图1
    • 清单项目2

      • 标题2
      • 回收服务2

    我认为从性能的角度来看,这种方法并不好。我说得对吗?我只需要找到最佳实践。非常感谢。

    4 回复  |  直到 8 年前
        1
  •  5
  •   Shashwat    8 年前

    请不要使用嵌套滚动。它将违背“回收者视图”的目的,并将所有内容保留在内存中,因为两个回收者的高度都将设置为最大。 相反,请进行以下两种选择:

    1.如果您没有特定背景,请创建一个带有适配器的RecyclerView,如下所示:

    public class MyRecyclerAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{
    
        ArrayList<Integer> data = new ArrayList<>();
        private final int VIEW_TYPE_TEXTVIEW = 0;
        private final int VIEW_TYPE_ITEM_1 = 1;
        private final int VIEW_TYPE_ITEM_2 = 2;
        private final LayoutInflater inflater;
        private final ArrayList<Integer> data;
    
        public MyRecyclerAdapter(Context ctx, ArrayList<Integer> data){
            this.context = ctx;
            this.data = data;
            inflater = LayoutInflater.from(context);
        }
    
        @Override
        public int getItemViewType(int position) {
            return data.get(position);
        }
    
        @NonNull
        @Override
        public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
            if(viewType == VIEW_TYPE_TEXTVIEW){
                View view = inflater.inflate(R.layout.simple_textview, parent, false);
                return new TextViewHolder(view);
            }else if(viewType == VIEW_TYPE_ITEM_1){
                View view = inflater.inflate(R.layout.item_top_recycler, parent, false);
                return new Item1Holder(view);
            }else{
                View view = inflater.inflate(R.layout.item_bottom_recycler, parent, false);
                return new Item2Holder(view);
            }
        }
    
        @Override
        public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
            if(holder instanceof TextViewHolder){
                ((TextViewHolder) holder).textView.setText(...);
            }else if(holder instanceof Item1Holder){
                ((Item1Holder) holder).itemTextView.setText(...);
            }else if(holder instanceof Item2Holder){
                ((Item2Holder) holder).itemTextView.setText(...);
            }
        }
    
        @Override
        public int getItemCount() {
            return data.size();
        }
    
        class TextViewHolder extends RecyclerView.ViewHolder {
    
    
            TextView textView;
    
            public HeaderHolder(View itemView) {
                super(itemView);
                textView = itemView.findViewById(R.id.tv);
            }
        }
        class Item1Holder extends RecyclerView.ViewHolder {
    
    
            TextView itemTextView;
    
            public HeaderHolder(View itemView) {
                super(itemView);
                itemTextView = itemView.findViewById(R.id.tv);
            }
        }
        class Item2Holder extends RecyclerView.ViewHolder {
    
    
            TextView itemTextView;
    
            public HeaderHolder(View itemView) {
                super(itemView);
                itemTextView = itemView.findViewById(R.id.tv);
            }
        }
    }
    

    然后按如下方式设置适配器:

    ArrayList<Integer> data = new ArrayList<>();
    //Adding first textview
    data.add(0);
    //Adding 10 elements of first RecyclerView
    for(int i = 0; i<10; i++){
        data.add(1);
    }
    //Adding second textview
    data.add(0);
    //Adding 10 elements of second RecyclerView
    for(int i = 0; i<10; i++){
        data.add(2);
    }
    
    adapter = new MyRecyclerAdapter(this, data);
    navView.setAdapter(adapter);
    

    这样,您也可以使用RecyclerView来包含您的文本视图。此方法将为您提供最佳优化。确保在getItemViewType()中为上循环视图、下循环视图和文本视图返回适当的视图类型。

    第二种方法是让一个RecyclerView包含4项:

    • 文本框
    • 线性布局
    • 文本框
    • 线性布局

    然后用项目动态填充这些线性布局。这将确保至少一个线性布局在看不见时被回收。即便如此,第一种方法还是比这好得多。

        2
  •  1
  •   Levi Moreira    8 年前

    首先,在一个屏幕上显示两个回收器视图不是一个好主意,除非有充分的理由。尝试在一个回收器视图中使用不同的标题部分。

    如果仍要使用,请将布局嵌入 NestedScrollView 设置回收视图的 nestedScrollingEnabled 财产 false

    recyclerView.setNestedScrollingEnabled(false);
    

    小贴士:退房 FastAdapter 这使工作更容易。

        3
  •  1
  •   Kalyan Dechiraju    8 年前

    无论你想要实现什么,都要更好地完成,如下面的链接所示: http://khmertechtrain.tk/index.php/2017/10/03/create-a-vertical-scroll-and-horizontal-scroll-app-like-google-play-store/

    此外,如果所有视图都相似,则需要使用RecycledViewPool在多个RecyclerViews之间共享视图。

        4
  •  0
  •   Benson Githinji    7 年前

    你应该试试NestedScrollView解决方案,你说它最接近你想要的:

    NestedScrollView
       TextView
       RecyclerView
       TextView
       RecyclerView
    

    要实现平滑滚动,您需要在“回收器”视图中设置属性:

     recyclerView.setNestedScrollingEnabled(false);
    

    这样,布局将滚动NestedScrollView,而不是RVs。