Reputation: 5
I'm using a custom adapter to load 20 items from a JSON string as well as implement ads in the 4th and 14th position. What I'm encountering is that when I scroll to view item #19, it crashes with the error in the title.
I know that the error is saying that it's trying to access an index that is not in the array but I think it's because it's included the adViews in the index (which it shouldn't). I feel like this is something simple that I am missing but please help. Here are my 2 adapters:
public class ListViewAdapter extends BaseAdapter implements AdListener {
private final Activity activity;
private final BaseAdapter delegate;
public ListViewAdapter(Activity activity, BaseAdapter delegate) {
this.activity = activity;
this.delegate = delegate;
}
@Override
public int getCount() {
// Total count includes list items and ads.
return delegate.getCount() + 2;
}
@Override
public Object getItem(int position) {
// Return null if an item is an ad. Otherwise return the delegate item.
if (isItemAnAd(position)) {
return null;
}
return delegate.getItem(position - 1);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (isItemAnAd(position)) {
if (convertView instanceof AdView) {
return convertView;
} else {
AdView adView = new AdView(activity, AdSize.SMART_BANNER,"AD ID (removed for post)" );
AdRequest adRequest = new AdRequest();
adView.loadAd(adRequest);
return adView;
}
} else {
return delegate.getView(position-1, convertView, parent);
}
}
@Override
public int getViewTypeCount() {
return delegate.getViewTypeCount() + 1;
}
@Override
public int getItemViewType(int position) {
if (isItemAnAd(position)) {
return delegate.getViewTypeCount();
} else {
return delegate.getItemViewType(getOffsetPosition(position));
}
}
@Override
public boolean areAllItemsEnabled() {
return false;
}
@Override
public boolean isEnabled(int position) {
return (!isItemAnAd(position)) && delegate.isEnabled(getOffsetPosition(position));
}
private boolean isItemAnAd(int position) {
// Place an ad at the first and last list view positions.
return (position == 4 || position == 14);
}
@Override
public void onDismissScreen(Ad arg0) {
}
@Override
public void onFailedToReceiveAd(Ad arg0, AdRequest.ErrorCode arg1) {
}
@Override
public void onLeaveApplication(Ad arg0) {
}
@Override
public void onPresentScreen(Ad arg0) {
}
@Override
public void onReceiveAd(Ad arg0) {
}
private int getOffsetPosition(int position) {
return position - 1;
}
}
Here's the custom adapter which sets the listview:
class CustomMovieAdapter extends BaseAdapter {
private ArrayList<SearchResults> searchArrayList;
private LayoutInflater mInflater;
public CustomMovieAdapter(Context context, ArrayList<SearchResults> results){
searchArrayList = results;
mInflater = LayoutInflater.from(context);
}
@Override
public int getCount() {
return searchArrayList.size()+2;
}
@Override
public Object getItem(int position) {
return searchArrayList.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = new ViewHolder();
if(convertView == null){
convertView = mInflater.inflate(R.layout.list_item, null);
holder = new ViewHolder();
assert convertView != null;
holder.txtRating = (TextView) convertView.findViewById(R.id.movieRating);
holder.txtMovieName = (TextView) convertView.findViewById(R.id.movieName);
holder.txtMovieSize = (TextView) convertView.findViewById(R.id.movieSize);
holder.txtImdbRating = (TextView) convertView.findViewById(R.id.imdbScore);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.txtRating.setText(searchArrayList.get(position+1).getRating());
holder.txtMovieName.setText(searchArrayList.get(position+1).getName());
holder.txtMovieSize.setText(searchArrayList.get(position+1).getSize());
holder.txtImdbRating.setText(searchArrayList.get(position+1).getImdbRating());
return convertView;
}
class ViewHolder {
TextView txtRating;
TextView txtMovieName;
TextView txtMovieSize;
TextView txtImdbRating;
}
}
Upvotes: 0
Views: 2232
Reputation: 157467
@Override
public int getCount() {
// Total count includes list items and ads.
return delegate.getCount() + 2;
}
you should return the size of the dataset without changing it. If you need to show more items, add those to the dataset. Changing it with
@Override
public int getCount() {
// Total count includes list items and ads.
return delegate.getCount() ;
}
Should fix your exception.
Edit, in getView you should avoid tampering the position android is providing you:
position+1
Upvotes: 1