當試圖返回視圖類型作爲數據在我的數組中的位置的函數時,我得到一個IndexOutOfBoundsException。我有兩個數據來源。一個是廣告,另一個是名稱和位置的列表。在RecyclerAdapter中處理數組之前,是否需要將數組合併成一個數組?我寧願不,特別是如果原則上它們可以是不同的類型,即圖像與文本。我的getItemCount()
方法正確地返回兩個數組的總和大小。爲什麼我得到這個異常?我如何在兩種不同視圖類型中實現顯示來自兩個不同源的數據的預期結果?具有多種視圖類型的RecyclerAdapter中的IndexOutOfBoundsException
我的主要活動:
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 HeterogeneousRecyclerAdapter(List