You're getting the NullPointerExceptions
because you're inflating two types of views and when you scroll Android will reuse your views but at some point it will bring you R.layout.list_item_entry
for isSection()
evaluated to true or vice-versa: R.layout.list_item_section
for isSection()
evaluated to false.
What you need to do is to implement two other methods in your adapter:
- getViewTypeCount()
this needs to return the number of view types you're inflating. In your case you need to return 2.
- getItemViewType(int position)
- based in the position, you need to return either 0, either 1.
Now, in your adapter detect first what is the item view type by calling getItemViewType
and then apply your current logic.
EDIT With a blind coding based on above the getView
method would look something like below (I didn't check how compilable this would be, but I am sure you would understand what I meant):
@Override
public int getViewTypeCount() {
return 2;
}
@Override
public int getItemViewType(int position) {
Item i = items.get(position);
if(i.isSection()) {
return 0;
}
return 1;
}
@Override
public View getView(final int position, View v, ViewGroup parent) {
final Item i = items.get(position);
int itemViewType = getItemViewType(position);
ViewHolder viewHolder = null;
if (itemViewType == 0) {
if (v == null) {
viewHolder = new ViewHolder();
v = vi.inflate(R.layout.list_item_section, null);
viewHolder.mSectionView = (TextView) v.findViewById(R.id.list_item_section_text);
v.setTag(mHolder);
} else {
viewHolder = (ViewHolder) v.getTag();
}
v.setOnClickListener(null);
v.setOnLongClickListener(null);
v.setLongClickable(false);
//final TextView sectionView = (TextView) v.findViewById(R.id.list_item_section_text);
viewHolder.mSectionView.setTypeface(StaticUtils.sTypeFace(context));
viewHolder.mSectionView.setText(mHolder.s.getTitle());
v.setEnabled(false);
} else {
EntryItem e = (EntryItem) i;
//v = vi.inflate(R.layout.list_item_entry, null);
if (v == null) {
viewHolder = new ViewHolder();
v = (View) vi.inflate(R.layout.list_item_entry, null);
viewHolder.mTitle = (TextView) v.findViewById(R.id.list_item_entry_title);
viewHolder.mImg = (ImageView) v.findViewById(R.id.list_item_entry_drawable);
viewHolder.mImg.getLayoutParams().height = mIvPrams;
viewHolder.mImg.getLayoutParams().width = mIvPrams;
v.setTag(mHolder);
// Do some initialization
} else {
viewHolder = (ViewHolder) v.getTag();
}
//mHolder.mTitle.setTypeface(StaticUtils.sTypeFace(context));
//mHolder.mTitle.setSelected(true);
if (viewHolder.mTitle != null)
viewHolder.mTitle.setText(mHolder.e.title);
imageLoader.displayImage(e.imgUrl, viewHolder.mImg, options, animateFirstListener);
}
return v;
}
An observation: don't keep the data model class in the Holder class since the holder will be reused in other similar views in a different position and there the data model class that you keep in Holder will not be valid for that position. You have already the getItem(position)
method available. Use that instead!