如何在一个布局中实现多个recyclerviews?
How to implement multiple recyclerviews in one layout?
我想创建一个窗格,其中有两个 RecyclerView
(比如 'MyItems'、'AllItems')。我创建了垂直 LinearLayout
,其中有 TextView
作为标题和 RecyclerView
。像这样:
<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
中,但我得到的最接近的是滚动 没有流畅的动画 .
我的问题是,这种方法是否有效,如果有效,是否有办法在 NestedScrollView
中添加平滑滚动?或者我应该使用另一种方法来实现它,例如创建包含两个项目的 ListView
,其布局包含 TextView
和 RecyclerView
?
ListView
列表项目 1
- 标题 1
- 回收视图 1
列表项 2
- 标题 2
- RecyclerView2
我认为从性能方面来看这种方法并不好。我对吗?我只需要为此找到最佳实践。谢谢。
您应该尝试您所说的最接近您想要的 NestedScrollView 解决方案:
NestedScrollView
TextView
RecyclerView
TextView
RecyclerView
为了流畅滚动,您需要在回收站视图中设置 属性:
recyclerView.setNestedScrollingEnabled(false);
这样您的布局将滚动 NestedScrollView 而不是 RV。
首先,除非有充分的理由,否则在一个屏幕上显示两个回收站视图并不是一个好主意。在一个回收器视图中尝试使用 headers 的不同部分。
如果还想用,把layout嵌入NestedScrollView
,设置recyclerView的nestedScrollingEnabled
属性为false
recyclerView.setNestedScrollingEnabled(false);
提示:查看 FastAdapter 可以使工作更轻松。
请不要使用嵌套滚动。这将破坏回收站视图的目的,并将所有内容保留在内存中,因为两个回收站的高度都将设置为最大值。
而是继续进行以下两个选择:
1.If您没有特定的背景,创建一个带有适配器的 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 来包含您的文本视图。这种方法会给你最好的优化。确保您 return 在 getItemViewType() 中为上层 recyclerView、下层 RecyclerView 和 TextView 设置了适当的 VIEW_TYPE。
第二种方法是让一个 RecyclerView 包含 4 个项目:
- TextView
- 线性布局
- TextView
- 线性布局
然后用项目动态填充这些 LinearLayouts。这将确保至少有一个 Linearlayout 在不可见时被回收。即使那样,第一种方法也会比这好得多。
无论您想要实现什么,最好按照下面 link 中的说明进行:
http://khmertechtrain.tk/index.php/2017/10/03/create-a-vertical-scroll-and-horizontal-scroll-app-like-google-play-store/
此外,如果所有视图都相似,您将需要使用 RecycledViewPool 以便在多个 RecyclerView 之间共享视图。
我想创建一个窗格,其中有两个 RecyclerView
(比如 'MyItems'、'AllItems')。我创建了垂直 LinearLayout
,其中有 TextView
作为标题和 RecyclerView
。像这样:
<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
中,但我得到的最接近的是滚动 没有流畅的动画 .
我的问题是,这种方法是否有效,如果有效,是否有办法在 NestedScrollView
中添加平滑滚动?或者我应该使用另一种方法来实现它,例如创建包含两个项目的 ListView
,其布局包含 TextView
和 RecyclerView
?
ListView
列表项目 1
- 标题 1
- 回收视图 1
列表项 2
- 标题 2
- RecyclerView2
我认为从性能方面来看这种方法并不好。我对吗?我只需要为此找到最佳实践。谢谢。
您应该尝试您所说的最接近您想要的 NestedScrollView 解决方案:
NestedScrollView
TextView
RecyclerView
TextView
RecyclerView
为了流畅滚动,您需要在回收站视图中设置 属性:
recyclerView.setNestedScrollingEnabled(false);
这样您的布局将滚动 NestedScrollView 而不是 RV。
首先,除非有充分的理由,否则在一个屏幕上显示两个回收站视图并不是一个好主意。在一个回收器视图中尝试使用 headers 的不同部分。
如果还想用,把layout嵌入NestedScrollView
,设置recyclerView的nestedScrollingEnabled
属性为false
recyclerView.setNestedScrollingEnabled(false);
提示:查看 FastAdapter 可以使工作更轻松。
请不要使用嵌套滚动。这将破坏回收站视图的目的,并将所有内容保留在内存中,因为两个回收站的高度都将设置为最大值。 而是继续进行以下两个选择:
1.If您没有特定的背景,创建一个带有适配器的 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 来包含您的文本视图。这种方法会给你最好的优化。确保您 return 在 getItemViewType() 中为上层 recyclerView、下层 RecyclerView 和 TextView 设置了适当的 VIEW_TYPE。
第二种方法是让一个 RecyclerView 包含 4 个项目:
- TextView
- 线性布局
- TextView
- 线性布局
然后用项目动态填充这些 LinearLayouts。这将确保至少有一个 Linearlayout 在不可见时被回收。即使那样,第一种方法也会比这好得多。
无论您想要实现什么,最好按照下面 link 中的说明进行: http://khmertechtrain.tk/index.php/2017/10/03/create-a-vertical-scroll-and-horizontal-scroll-app-like-google-play-store/
此外,如果所有视图都相似,您将需要使用 RecycledViewPool 以便在多个 RecyclerView 之间共享视图。