多个ViewTypes的适配器计数问题

时间:2015-11-02 01:01:14

标签: android android-layout android-recyclerview adapter

我有一个适配器,其中有许多项目要作为列表显示在RecyclerView中。但我正在使用adMob来投放广告。因此,对于我想要投放广告的每个x项目。但我遇到的问题是我的适配器没有插入广告,而是为他们而不是提供应该在该位置的项目。我该如何解决这个问题?

要想到这一点,请说我的适配器有一个铅笔项目列表。但是对于每5支铅笔,我想展示一个蛋。所以,如果我有10支铅笔,我想看到所有10支铅笔加上2支鸡蛋:所以12件。但是现在我的适配器显示8支铅笔和2个鸡蛋。

我需要一个解决这个问题的一般方法,因为适配器可能正在处理游标(在我的情况下也是如此)。对于ArrayList,我可以添加虚拟占位符,但对于游标,我不知道我能做什么。

1 个答案:

答案 0 :(得分:0)

好吧,我们似乎可以把它分成多个子问题。

1)创建一般的多项目类型适配器

有几种方法可以做到这一点,但我通常采用的解决方案是创建一个ViewHolder工厂/活页夹,将项目类型映射到ViewHolder

public abstract class ViewHolderBinder<VH extends ViewHolder, T> {
    /**
     * Create a new ViewHolder for this binder's item type
     *
     * @param viewGroup
     * @return
     */
    public abstract VH newViewHolder(ViewGroup viewGroup);

    /**
     * Bind the data om the given item to the view holder
     *
     * @param viewHolder
     * @param item
     */
    public abstract void bindViewHolder(VH viewHolder, T item);
}

然后为每种类型的项创建一个ViewHolderBinder实例,并且Adapter需要维护逻辑以将每种类型的项映射到相应的ViewHolderBinder,例如使用HashMap<Integer, ViewHolderBinder>。映射可以是硬编码的,或者更好,在构造时使用项类型到绑定器映射添加方法addBinder来初始化适配器。 项类型值可以是固定常量,或者,如果每种类型的项由唯一类表示,您甚至可以使用类“hashCode()作为项类型来进一步简化。

然后使用活页夹创建一个实现getItemViewTypeonCreateViewHolderonBindViewHoldergetItemCount的通用适配器。

2)让上述适配器处理多个数据源

这基本上只是意味着你必须实现getItemCount,以便它结合来自所有来源的数据(比如游标+广告提供商),并创建一个方法public T getItem(int position),返回数据给定的位置。对于项目计数,它应该足够简单,只需将所有来源的计数相加;对于getItem,您必须实现逻辑以确保适配器位置映射到每个相应数据源的索引。

在每个第N项作为广告并且每个广告位于位置k * N的特定情况下,实现可能如下所示:

public T getItem(int position) {
  int adIndex = position / N;

  if (position % N == 0) {
    //TODO return the ad with index adIndex
  } else {
    int dataIndex = position - (adIndex + 1);
    //TODO return data with index dataIndex
  }
}

@Override
public int getItemCount() {
  int dataCount = getDataCount(); // From cursor.getCount() or whatever

  return dataCount + 1 + dataCount / N;
} 
相关问题