-1

这是我的情况。
我所拥有的:在右上角和自定义元素列表下方带有复选框(称为“checkAll”)的活动:TextView 和复选框。
我想要什么:当点击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;
}

我怎样才能避免这个问题?我如何检查带有不可见元素的大列表的所有复选框?

4

1 回答 1

1

为了实现这一点,您需要了解 ListView 的工作原理,即视图回收。在 Android 中创建列表时,会动态创建视图。当您向上和向下滚动时,离开屏幕的列表项需要清除其视图中的数据并重新填充下一个进入的项的信息。这发生在getView您的列表适配器中的方法中(顺便说一下,对你发帖很有帮助)。我相信这是您出现空指针异常的原因。这getChildAt方法只能返回可见的列表项,因为其他的目前不存在。第一个可见项目将是索引 0。因此,即使您的列表可能有 20 个项目,如果只有 5 个可见,getChildAt 只能返回 5 个,并且请求超出范围的视图可能会导致此异常。

我处理您的项目的方法是拥有一个记录您的列表项目和复选框状态的数据结构。一个非常简单的例子是一个布尔数组,其中真/假值对应于复选框是否被选中。调用时getView(),您可以使用position参数 a your 作为数组的索引,并根据此选中或取消选中该框。(如果你正确地回收你的视图,你可能应该做这样的事情)如果按下 Check All 按钮,那么只需使数组的每个元素都为真。

一些示例代码可以帮助您。

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 中的视图回收,因为它是一个关键概念,并且很好地处理它会为您节省大量时间和头痛。祝你好运。

于 2012-07-03T22:18:46.733 回答