这是我的情况
我拥有的内容:在自定义元素列表的右上方和下方带有复选框(称为“checkAll”)的活动:TextView和复选框。
我想要什么:当clA on checkAll时,会检查列表中每个项目的所有复选框。
问题:只有在屏幕上显示列表中的所有项目时,一切正常。当我有一个包含大量元素的列表(例如20)时,那么当点击checkAll我的应用程序崩溃时。 LogCat说我:行上的NullPointerException
CheckBox checkBoxInTheItemList = (CheckBox)
mList.getChildAt(i).findViewById(R.id.checkBox);
这是我的功能:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.list_layout_select_friend);
checkAll =(CheckBox)findViewById(R.id.checkBoxAll);
checkAll.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
if((checkAll.isChecked())){
for(int i=1;i<peopleSize;i++){//for each element of my array of Person
mList=(ListView) findViewById(R.id.list); //This is the id of my List
//in the list_layout_select_friend
CheckBox checkBoxInTheItemList = (CheckBox)
mList.getChildAt(i).findViewById(R.id.checkBox); //i try to get
//for each item of the List the relative checkBox.
checkBoxInTheItemList.setChecked(true);//Now i checked the checkBox
}
}
}
});
}
编辑:这是我的适配器,也是方法getView
public class NewQAAdapterSelectFriends extends BaseAdapter {
private LayoutInflater mInflater;
private Person[] data;
public NewQAAdapterSelectFriends(Context context) {
mInflater = LayoutInflater.from(context);
}
public void setData(Person[] data) {
this.data = data;
}
@Override
public int getCount() {
return data.length;
}
@Override
public Object getItem(int item) {
return data[item];
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = mInflater.inflate(R.layout.item_select_friends, null);
final ViewHolder viewHolder = new ViewHolder();
viewHolder.nameText=(TextView) convertView.findViewById(R.id.personName);
viewHolder.surnameText=(TextView) convertView.findViewById(R.id.personSurname);
viewHolder.contactImage=(ImageView) convertView.findViewById(R.id.personImage);
viewHolder.checkBox=(CheckBox)convertView.findViewById(R.id.checkBox);
convertView.setTag(viewHolder);
viewHolder.nameText.setTag(viewHolder.nameText);
viewHolder.nameText.setTag(viewHolder.surnameText);
viewHolder.contactImage.setTag(data[position]);
viewHolder.checkBox.setTag(data[position]);// is correct this line??????
} else {
}
ViewHolder holder = (ViewHolder) convertView.getTag();
holder.nameText.setText(data[position].getName());
holder.surnameText.setText(data[position].getSurname());
holder.contactImage.setImageResource(data[position].getPhotoRes());
holder.contactImage.setScaleType(ScaleType.FIT_XY);
//here i have to write something for the checkbox, right?
return convertView;
}
static class ViewHolder {
TextView nameText;
TextView surnameText;
ImageView contactImage;
CheckBox checkBox;
}
我怎么能避免这个问题? 如何检查包含隐形元素的大清单的所有复选框?
答案 0 :(得分:1)
为了实现这一点,您需要了解ListView的工作方式,即查看回收。在Android中创建列表时,将动态创建视图。当您向上和向下滚动时,列出屏幕外的项目需要清除其数据并清除数据,并重新填充下一个项目的信息。这会发生在列表适配器中的getView
方法中(顺便说一句,这对你来说非常有帮助)。我相信这是Null Pointer Exception的原因。 getChildAt
方法只能返回可见列表项,因为其他项目目前不存在。第一个可见项将是索引0.因此,即使您的列表可能有20个项目,如果只有5个可见,getChildAt只能返回5个,并且要求超出范围的视图可能会导致此异常。
我接近你的项目的方法是通过一个数据结构来记录你的列表项和复选框的状态。一个非常简单的示例是布尔数组,其中true / false值对应于是否选中该框。调用getView()
时,可以使用position
参数作为数组的索引,并根据此选中或取消选中该框。 (如果你正确地回收你的观点,你可能应该做这样的事情)如果按下全部检查按钮,那么只需使数组的每个元素都为真。
一些示例代码可以帮助您。
private boolean[] isCheckedArray; //Maintains the checked state of your
... //At some point, probably onCreate or whenever you get your data, initialize your array. If nothing every starts checked off, initialize the whole array to false
checkAll.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0){
for(int i=1;i<peopleSize;i++)
isCheckedArray[i] = true;
}
});
...
//And finally, in your getView function
@Override
public View getView(int position, View convertView, ViewGroup parent)
{
...
myCheckBox.setChecked(isCheckedArray[position])
...
}
希望这会有所帮助。我肯定会在Android中查看回收视图,因为它是一个关键概念,并且能够很好地处理它将为您节省大量时间和头痛。祝你好运。