为什么ListView getChildAt仅适用于某个索引?

时间:2015-03-17 13:14:46

标签: android android-layout android-listview android-linearlayout

我有ListView CheckBoxTextView。我正在尝试使用索引查找CheckBox。在我目前的测试场景中,我在ListView中有16个项目。以下代码一直工作到索引5并在此之后给出IllegalStateException。为什么会这样? 如何获取所有索引的CheckBox我认为它与Layout仅代表可见行有关。但即使我向下滚动,索引0也起作用,索引大于5不等。 ListView是类中的私有属性。代码:

public void inform(View v) {            
            TextView tv;
            CheckBox cb;
            String s = "";
            int nrItems = lv.getCount();
            LinearLayout layout = (LinearLayout) lv.getChildAt(6);
            Toast.makeText(getApplicationContext(), Integer.toString(layout.getChildCount()), Toast.LENGTH_SHORT).show();
            cb = (CheckBox) layout.getChildAt(0);
            Toast.makeText(getApplicationContext(), Boolean.toString(cb.isChecked()), Toast.LENGTH_SHORT).show();
}

2 个答案:

答案 0 :(得分:2)

实际上只有可见的视图。如果向下滚动以便看到第6行到第10行,那么getChildAt(0);实际上是第6行,因为它是第一个实际存在的视图

编辑:
您可能尝试做的是获取所有复选框的isChecked()值。事情是,屏幕上没有更多的复选框。因此,“所有复选框”永远不会全部为16。

复选框本身应该只是某些数据的表示。你不应该依赖isChecked上的事实来做某事。您应该保留一个单独的列表或布尔值数组,表示是否选中该复选框。这在重用行时很有用,我猜你不会这样做。

答案 1 :(得分:1)

将ListView与您自己的适配器一起使用。 例如:

public class SampleAdapter extends BaseAdapter {

List<Item> mData ; // Don't forget to instantiate this



@Override
public int getCount() {
    return mData.size();
}

@Override
public Object getItem(int position) {
    return mData.get(position);
}

public void setIsChecked(boolean isChecked){
    for(Item item : mData){
        item.isChecked = isChecked;
    }
    notifyDataSetChanged();
}

@Override
public long getItemId(int position) {
    return 0;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    //Some example. Create or inflate view here
    if(convertView == null)
        convertView = new CheckBox(parent.getContext());
    convertView.isChecked(mData.isChecked);

    return convertView ;
}
}

<强>更新

要点是您需要直接更改数据而不是视图。在为适配器调用notofyDataSetChanged()之后,所有视图都将自动更改。