我正在使用带有部分和截面标题的listView。以下是没有视图持有人类的适配器的GetView方法,它可以正常工作,但是当滚动几次时,冻结UI并在多个设备上杀死该应用程序。
@Override
public View getView(int position, View v, ViewGroup parent)
{
//View v = convertView;// = convertView;
//System.out.println("getView " + position + " " + convertView);
final Item i = items.get(position);
if (i != null)
{
if(i.isSection())
{
SectionItem si = (SectionItem)i;
v = vi.inflate(R.layout.list_item_section, null);
v.setOnClickListener(null);
v.setOnLongClickListener(null);
v.setLongClickable(false);
final TextView sectionView = (TextView) v.findViewById(R.id.list_item_section_text);
sectionView.setTypeface(StaticUtils.sTypeFace(context));
sectionView.setText(si.getTitle());
v.setEnabled(false);
}
else
{
EntryItem ei = (EntryItem)i;
v = vi.inflate(R.layout.list_item_entry, null);
final TextView title = (TextView)v.findViewById(R.id.list_item_entry_title);
final ImageView mImg = (ImageView)v.findViewById(R.id.list_item_entry_drawable);
mImg.getLayoutParams().height = mIvPrams;
mImg.getLayoutParams().width = mIvPrams;
title.setTypeface(StaticUtils.sTypeFace(context));
title.setSelected(true);
if (title != null)
title.setText(ei.title);
imageLoader.displayImage(ei.imgUrl, mImg, options, animateFirstListener);
}
}
return v;
}
现在,我试图将视图持有人类实现,以改善冻结问题。以下是我为适配器实施的带有View Holder类的代码。但是,当我滚动下面的实现时,ListView将全部混乱。它无法保存其元素的索引。如果我尝试进行更改,当我从下到顶部滚动时,我也会得到NullPoInterException。
。@Override
public View getView(final int position, View v, ViewGroup parent)
{
//View v = null;// = convertView;
//System.out.println("getView " + position + " " + convertView);
final Item i = items.get(position);
if (i != null)
{
if(i.isSection())
{
/*if (convertView == null) {
v = (View) vi.inflate(R.layout.list_item_section, null);
// Do some initialization
} else {
v = convertView;
}*/
if(v==null)
{
mHolder = new ViewHolder();
v = vi.inflate(R.layout.list_item_section, null);
mHolder.s = (SectionItem)i;
mHolder.mSectionView = (TextView) v.findViewById(R.id.list_item_section_text);
v.setTag(mHolder);
}
else
{
mHolder=(ViewHolder)v.getTag();
//v = convertView;
}
v.setOnClickListener(null);
v.setOnLongClickListener(null);
v.setLongClickable(false);
//final TextView sectionView = (TextView) v.findViewById(R.id.list_item_section_text);
mHolder.mSectionView.setTypeface(StaticUtils.sTypeFace(context));
mHolder.mSectionView.setText(mHolder.s.getTitle());
v.setEnabled(false);
}
else
{
//v = vi.inflate(R.layout.list_item_entry, null);
if (v == null) {
mHolder = new ViewHolder();
v = (View) vi.inflate(R.layout.list_item_entry, null);
mHolder.e = (EntryItem)i;
mHolder.mTitle = (TextView)v.findViewById(R.id.list_item_entry_title);
mHolder.mImg = (ImageView)v.findViewById(R.id.list_item_entry_drawable);
mHolder.mImg.getLayoutParams().height = mIvPrams;
mHolder.mImg.getLayoutParams().width = mIvPrams;
v.setTag(mHolder);
// Do some initialization
} else {
mHolder=(ViewHolder)v.getTag();
}
//mHolder.mTitle.setTypeface(StaticUtils.sTypeFace(context));
//mHolder.mTitle.setSelected(true);
if (mHolder.mTitle != null)
mHolder.mTitle.setText(mHolder.e.title);
imageLoader.displayImage(mHolder.e.imgUrl, mHolder.mImg, options, animateFirstListener);
}
}
return v;
}
public class ViewHolder
{
TextView mSectionView, mTitle;
ImageView mImg;
EntryItem e;
SectionItem s;
}
我希望能为如何改进代码并为此适配器编写适当的视图持有人类的解决方案。
您正在获取NullPointerExceptions
,因为您正在夸大两种视图,并且滚动时,Android会重复使用您的视图,但是在某些时候,它会为您带来R.layout.list_item_entry
,以评估isSection()
反之亦然:R.layout.list_item_section
用于评估为false的isSection()
。
您需要做的是在适配器中实现其他两种方法:
-getViewTypeCount()
这需要返回要充气的视图类型的数量。在您的情况下,您需要返回2。 -getItemViewType(int position)
-基于位置,您需要返回0,要么1。
现在,在您的适配器中,首先通过调用 getItemViewType
来检测项目视图类型是什么,然后应用您的当前逻辑。
编辑带有基于上述getView
方法的盲目编码的看起来像下面的内容(我没有检查这是多么可编译,但是我敢肯定您会理解我的意思):
@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;
}
一个观察:不要将数据模型类保留在持有人类类中。您已经具有可用的getItem(position)
方法。而是使用它!