如何将两个适配器设置为一个RecyclerView?

Ham*_*sir 10 android android-adapter android-viewholder android-recyclerview fastadapter

我正在开发一个Android应用程序,其中我在'FirebaseDatabase`上存储两种不同类型的信息.

然后在MainActivity,我正在检索它们并向用户显示RecyclerView.这两个信息都是以不同的布局显示的,即两者的布局都不同,这就是为什么我有两个不同的Model类,现在有两个不同的适配器.我正在使用@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);
    }
Run Code Online (Sandbox Code Playgroud)

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);
    }
Run Code Online (Sandbox Code Playgroud)

由于recyclerview只有一个,我正在逐个设置2个不同的适配器,所以Recyclerview正在使用第二个适配器进行更新并仅显示其内容.

那么,如何将适配器显示或设置为相同的"RecyclerView"并显示存储在两个适配器中的内容.

Mar*_*nak 23

您不能在一个RecyclerView上设置两个适配器.但是,您可以创建一个处理两种类型项的自定义适配器.方法如下:

假设您需要显示两种类型对象:动物和B类.让我们处理最难的场景,也就是说,您的对象需要完全不同的布局来显示它们并完全不同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
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

首先,向适配器添加表示视图类型的常量:

private static final int ITEM_TYPE_ANIMAL;
private static final int ITEM_TYPE_BEVERAGE;
Run Code Online (Sandbox Code Playgroud)

为简单起见,我们假设您将对象存储在列表中:

private List<Object> items = new ArrayList<>();

public MyAdapter(List<Object> items) {
    this.items.addAll(items);
    ...
}
Run Code Online (Sandbox Code Playgroud)

首先,您需要实现getItemViewType:

@Override
public int getItemViewType(int position) {
    if (items.get(position) instanceof Animal) {
        return ITEM_TYPE_ANIMAL;
    } else {
        return ITEM_TYPE_BEVERAGE;
    }
} 
Run Code Online (Sandbox Code Playgroud)

接下来,您使用内部的项目类型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);
    } 
} 
Run Code Online (Sandbox Code Playgroud)

最后绑定正确的视图持有者:

@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);
    } 
} 
Run Code Online (Sandbox Code Playgroud)

  • 可以,但只有当您对两种布局使用相同的 ViewHolder 时,此技巧才能发挥其全部潜力。否则,您会在创建和绑定中继续使用 if-else,并且收益很小。 (3认同)

Gas*_*lén 10

连接适配器

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
Run Code Online (Sandbox Code Playgroud)

  • 哈哈,它已重命名为 [ConcatAdapter](https://developer.android.com/reference/androidx/recyclerview/widget/ConcatAdapter) (2认同)