Я получаю исключение IndexOutOfBoundsException при попытке вернуть тип вида в зависимости от положения данных в моем массиве. У меня есть два источника данных. Один - это реклама, а другой - список имен и мест. Нужно ли объединять массивы в один массив, прежде чем обрабатывать его в RecyclerAdapter? Я бы предпочел, особенно, если в принципе они могут быть разных типов, то есть изображений и текста. Мой метод getItemCount()
правильно возвращает суммированный размер двух массивов. Почему я получаю это исключение? Как я могу достичь желаемого результата отображения данных из двух разных источников в двух разных типах представлений?IndexOutOfBoundsException в RecyclerAdapter с несколькими типами просмотра
Моя основная деятельность:
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()));
}
}
Мой утилизатор адаптер позволяет несколько представлений:
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());
}
}
}
Где я могу добавить объявления в список своих товаров? – santafebound
Только в последней строке конструктора адаптера. Теперь нет необходимости хранить ссылки на рекламу. – Neo
Хорошо, так что '' public HeterogenicRecyclerAdapter (список