首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >多视图类型的IndexOutOfBoundsException在RecyclerAdapter中的应用

多视图类型的IndexOutOfBoundsException在RecyclerAdapter中的应用
EN

Stack Overflow用户
提问于 2016-07-04 12:52:59
回答 3查看 651关注 0票数 1

当试图将视图类型作为数组中数据位置的函数返回时,我将获得一个IndexOutOfBoundsException。我有两个数据来源。一个是广告,另一个是名字和地点的列表。在RecyclerAdapter中处理数组之前,是否需要将数组组合成一个数组?我宁愿不这样做,尤其是在原则上它们可以是不同的类型,即图像和文本。我的getItemCount()方法正确地返回两个数组的总和大小。我为什么要得到这个例外?如何在两种不同的视图类型中显示来自两个不同源的数据?

我的主要活动:

代码语言:javascript
复制
public class MainActivity extends AppCompatActivity {

    private ArrayList<Object> getPresidentsArrayList() {
        ArrayList<Object> items = new ArrayList<>();
        items.add(new President("George Washington", "Mount Vernon"));
        items.add(new President("John Adams", "Braintree"));
        items.add(new President("Thomas Jefferson", "Monticello"));
        items.add(new President("James Madison", "Port Conway"));
        return items;
    }

    private ArrayList<Object> getAdsArrayList() {
        ArrayList<Object> ads = new ArrayList<>();
        ads.add(new Sponsored("Craft Beer 20% Off", "Budweiser"));
        ads.add(new Sponsored("Craft Beer 20% Off", "Budweiser"));
        ads.add(new Sponsored("Craft Beer 20% Off", "Budweiser"));
        ads.add(new Sponsored("Craft Beer 20% Off", "Budweiser"));
        return ads;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        bindDataToAdapter(recyclerView);

    }

    private void bindDataToAdapter(RecyclerView recyclerView) {
        recyclerView.setAdapter(new HeterogeneousRecyclerAdapter(getPresidentsArrayList(), getAdsArrayList()));
    }

}

我的回收器适配器允许多个视图:

代码语言:javascript
复制
public class HeterogeneousRecyclerAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    private List<Object> items;
    private List<Object> ads;
    private final int PRESIDENT = 0, SPONSORED = 1;

    public HeterogeneousRecyclerAdapter(List<Object> items, List<Object> ads) {
        this.items = items;
        this.ads = ads;
    }

    @Override
    public int getItemCount() {
        return (this.items.size() + this.ads.size());
    }

    @Override
    public int getItemViewType(int position) {
        if (items.get(position) instanceof President) {
            return PRESIDENT;
        } else if (ads.get(position) instanceof Sponsored) {
            return SPONSORED;
        }
        return -1;
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {

        RecyclerView.ViewHolder viewHolder;
        LayoutInflater inflater = LayoutInflater.from(viewGroup.getContext());

        switch (viewType) {
            case PRESIDENT:
                View v1 = inflater.inflate(R.layout.layout_viewholder1, viewGroup, false);
                viewHolder = new ViewHolder1(v1);
                break;
            case SPONSORED:
                View v2 = inflater.inflate(R.layout.layout_viewholder2, viewGroup, false);
                viewHolder = new ViewHolder2(v2);
                break;
            default:
                View v = inflater.inflate(android.R.layout.simple_list_item_1, viewGroup, false);
                viewHolder = new RecyclerViewSimpleTextViewHolder(v);
                break;
        }
        return viewHolder;
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) {
        switch (viewHolder.getItemViewType()) {
            case PRESIDENT:
                ViewHolder1 vh1 = (ViewHolder1) viewHolder;
                configureViewHolder1(vh1, position);
                break;
            case SPONSORED:
                ViewHolder2 vh2 = (ViewHolder2) viewHolder;
                configureViewHolder2(vh2, position);
                break;
            default:
                RecyclerViewSimpleTextViewHolder vh = (RecyclerViewSimpleTextViewHolder) viewHolder;
                configureDefaultViewHolder(vh, position);
                break;
        }
    }

    private void configureDefaultViewHolder(RecyclerViewSimpleTextViewHolder vh, int position) {
        vh.getLabel().setText((CharSequence) items.get(position));
    }

    private void configureViewHolder1(ViewHolder1 vh1, int position) {
        President president = (President) items.get(position);
        if (president != null) {
            vh1.getLabel1().setText(president.getName());
            vh1.getLabel2().setText(president.getHometown());
        }
    }

    private void configureViewHolder2(ViewHolder2 vh2, int position) {
        Sponsored sponsored = (Sponsored) ads.get(position);
        if (sponsored != null) {
            vh2.getLabel1().setText(sponsored.getName());
            vh2.getLabel2().setText(sponsored.getCompany());
        }
    }
}
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-07-04 12:59:05

您需要创建一个公共列表,同时添加两个列表。做以下几件事-

代码语言:javascript
复制
    public HeterogeneousRecyclerAdapter(List<Object> items, List<Object> ads) {
        this.items = items;
        items.addAll(ads);
    }

现在更改get项目计数-

代码语言:javascript
复制
@Override
public int getItemCount() {
    return this.items.size();
}

希望它对你会很好:)

票数 3
EN

Stack Overflow用户

发布于 2016-07-04 12:56:44

getItemCount的实现是错误的

代码语言:javascript
复制
 @Override
 public int getItemCount() {
     return (this.items.size() + this.ads.size());
 }

如果两者都不返回0,则返回的值大于两个集合的大小。这就是为什么你要得到一个ArrayIndexOutBoundException。请记住,position0getItemCount - 1,在您的示例中,itemsads都不包含getItemCount对象。

票数 2
EN

Stack Overflow用户

发布于 2016-07-04 13:04:01

getItemViewType的实现是错误的。让我们假设您的items列表有4个条目,ads有3个广告对象。现在您的getItemViewType将返回7。现在系统将开始查找这7个对象的项目类型。让我们假设它希望在RecyclerView中找到第5行的类型。现在,在您的方法中,getItemViewType第1行本身抛出了这个异常,因为items列表的大小仅为4。

要么你必须将这两个列表合并在一个列表中,要么在回收商的视图中有一些订单,就像所有的广告都会出现在物品之前。在这种情况下,您还必须修改getItemViewType

希望这能有所帮助。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38185274

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档