【发布时间】:2014-05-19 18:13:32
【问题描述】:
我正在显示一个 ListView,起初它工作得很好 - 一切都显示和滚动正常。 ListView 中有 12 个项目。然后我尝试减少 ListView 中的项目数量,因此我减少了数据集的大小,它在适配器的 getView() 中崩溃,因为 getView() 被调用位置值对于新的较小列表来说太大了,导致数组索引超出范围。
来源片段:
在 onCreate() 我将我的列表视图附加到 XML
setContentView(R.layout.mylist);
lv = getListView();
我创建适配器并绑定它。 . .
mylistadapter = new MyListAdapter(MyListActivity.this);
setListAdapter(mylistadapter); // bind the adapter
...数据源是一个名为 listItems 的 ArrayList。第一次里面有 12 个项目;后来我清除它并添加6个项目。
public static ArrayList<String>listItems=new ArrayList<String>();
在我清除它并添加 6 个新项目后,我调用了 notifyDataSetChanged()。
在我的适配器(BaseAdapter)中,我对 getCount() 的覆盖看起来像这样。将 listItems 缩小到 6 后,它会正确返回 6。
@Override
public int getCount() {
return listItems.size();
}
为了验证 notifyDataSetChanged() 是否被调用,我编写了一个覆盖它来进行日志记录并向自己证明它确实被调用了。不管有没有这个覆盖,行为都是一样的。
// just overriding notifyDataSetChanged() to instrument it
@Override
public void notifyDataSetChanged()
{
Log.e ("notifyDataSetChanged()...", "listItems.size()=" + String.valueOf(listItems.size()) + " lv.getCount()=" + String.valueOf(lv.getCount()) ); //!! debugging
super.notifyDataSetChanged();
}
getView() 看起来像这样。它在 BOOM 评论中爆炸,因为位置是 6,而 listItems 只有 6 个项目([0]-[5]
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
boolean select;
Log.e ("getView() ... " , "position=" + String.valueOf(position) +
" AdapterCount=" + String.valueOf(getCount()) + "..." ); //!! debugging
if (convertView == null) {
LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = vi.inflate(R.layout.mylistitem, null);
//This is still needed even though we point to an XML description
convertView.setLayoutParams(new ListView.LayoutParams(
ListView.LayoutParams.MATCH_PARENT,
ListView.LayoutParams.MATCH_PARENT));
holder = new ViewHolder();
convertView.setTag(holder);
holder.cV1.setTag(holder); //These views need tags for onClick()
}
else {
holder = (ViewHolder)convertView.getTag();
}
int lvCount = lv.getCount(); // for debugging
//Must set this in both cases
holder.itemView.setText(listItems.get(position)); //BOOM
return convertView;
} // end getView
由于适配器知道它的数据集listItems中只有6个项目,它应该只用[0]-[5]调用getView(),但实际上它用位置值调用它直到[11],这是旧列表的最大值。这就是它崩溃的原因。你可以看到我也在哪里得到 ListView 的计数,用于诊断;也是6。那么更高的位置值来自哪里?
【问题讨论】:
标签: android