如何将两个适配器设置为一个 RecyclerView?
Posted
技术标签:
【中文标题】如何将两个适配器设置为一个 RecyclerView?【英文标题】:How to set two adapters to one RecyclerView? 【发布时间】:2017-04-02 16:51:15 【问题描述】:我正在开发一个 android 应用程序,其中我在“FirebaseDatabase”上存储了两种不同类型的信息。
然后在MainActivity
中,我正在检索它们并在RecyclerView
中显示给用户。这两个信息都应该以不同的布局显示,即它们的布局不同,这就是为什么我有两个制作两个不同的模型类,现在有两个不同的适配器。我正在使用@MikePenz 的FastAdapter
所以,我所做的就是按照从数据库中获取信息的相同顺序在 recyclerview 上设置适配器:
1.
public void prepareDataOfSRequests()
gModelClass = new GModelClass(postedBy, ***, ***, ***, "error", ***, formattedTime, currentLatitude, currentLongitude, utcFormatDateTime, userEmail, userID, null, ***, itemID);
fastItemAdapter.add(0, gModelClass);
recyclerView.setAdapter(fastItemAdapter);
recyclerView.smoothScrollToPosition(0);
emptyRVtext.setVisibility(View.INVISIBLE);
2.
public void prepareDataOfERequests()
eModelClass = new EModelClass(***, ***, ***, ***, "error", ***, formattedTimeE, currentLatitudeE, currentLongitudeE, utcFormatDateTimeE, userEmailE, userIDE, null, ***, ***, ***, ***, itemID);
fastItemAdapterER.add(eventRequestsModelClass);
recyclerView.setAdapter(fastItemAdapterER);
recyclerView.smoothScrollToPosition(0);
emptyRVtext.setVisibility(View.INVISIBLE);
由于 recyclerview 只有一个,并且我正在逐个设置 2 个不同的适配器,因此 recyclerview 正在使用第二个适配器进行更新并仅显示其内容。
那么,如何将两个适配器显示或设置为相同的“RecyclerView”,并且可以显示存储在两个适配器中的内容。
【问题讨论】:
你可以做两种类型的viewholder并要求一个接口......如果项目是instanceOf class1,则绘制viewholder1,否则为viewholder2 @JCDecary 但我必须在回收站视图中显示它们。我认为您的代码将显示其中一个。对吗? 不,你将拥有两者,你只需要覆盖 getitemcount @JCDecary 哦,好吧...兄弟,你能不能写一些代码实际上我不是很专业,所以很难理解。如果您可以编写一些代码作为答案,那就太好了。请。 @Marcin Jedynak 比我快 【参考方案1】:您不能在一个 RecyclerView 上设置两个适配器。但是,您可以制作一个处理两种类型项目的自定义适配器。方法如下:
假设您需要显示两种类型的对象A动物和Beverages。让我们处理最困难的情况,即您的对象需要完全不同的布局来显示它们,并且完全不同的ViewHolders
。这里是ViewHolders
:
public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
...
private static class AnimalViewHolder extends RecyclerView.ViewHolder
public AnimalViewHolder(View itemView)
super(itemView);
// prepare your ViewHolder
public void bind(Animal animal)
// display your object
private static class BeverageViewHolder extends RecyclerView.ViewHolder
// like the one above
...
首先向适配器添加代表视图类型的常量:
private static final int ITEM_TYPE_ANIMAL;
private static final int ITEM_TYPE_BEVERAGE;
为简单起见,假设您将对象存储在列表中:
private List<Object> items = new ArrayList<>();
public MyAdapter(List<Object> items)
this.items.addAll(items);
...
首先你需要实现getItemViewType
:
@Override
public int getItemViewType(int position)
if (items.get(position) instanceof Animal)
return ITEM_TYPE_ANIMAL;
else
return ITEM_TYPE_BEVERAGE;
接下来使用onCreateViewHolder
中的项目类型:
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
if (viewType == ITEM_TYPE_ANIMAL)
layoutInflater.inflate(R.layout.item_animal, parent, false);
return new AnimalViewHolder(view);
else
layoutInflater.inflate(R.layout.item_beverage, parent, false);
return new BeverageViewHolder(view);
最后你绑定了正确的视图持有者:
@Override
public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position)
Object item = items.get(position);
if (viewHolder instanceof AnimalViewHolder)
((AnimalViewHolder) viewHolder).bind((Animal) item);
else
((BeverageViewHolder) viewHolder).bind((Beverage) item);
【讨论】:
您可以在getItemViewType
中返回您的布局资源 ID。然后在 onCreateViewHolder
中,只需在方法参数中膨胀 viewType
。
你可以,但是只有在两种布局都使用相同的 ViewHolder 时,这个技巧才能发挥其全部潜力。否则,您在创建和绑定中继续使用 if-else,并且收益微乎其微。【参考方案2】:
连接适配器
ConcatAdapter 是recyclerview:1.2.0-alpha02 中的一个新类 这使您能够顺序组合多个适配器 显示在单个 RecyclerView 中。这使您能够更好地 封装您的适配器,而不必组合许多数据 源到单个适配器中,使它们保持专注和可重用。
来源:https://medium.com/androiddevelopers/merge-adapters-sequentially-with-mergeadapter-294d2942127a
用法
val firstAdapter: FirstAdapter = …
val secondAdapter: SecondAdapter = …
val thirdAdapter: ThirdAdapter = …
val concatAdapter = ConcatAdapter(firstAdapter, secondAdapter,
thirdAdapter)
recyclerView.adapter = concatAdapter
【讨论】:
大声笑,它已重命名为ConcatAdapter【参考方案3】:如果你愿意,你绝对可以写一个中间层来接受多个适配器。
如果你有兴趣,可以看看我是做什么的。 https://github.com/Jintin/MixAdapter
【讨论】:
以上是关于如何将两个适配器设置为一个 RecyclerView?的主要内容,如果未能解决你的问题,请参考以下文章