为什么 ListView getChildAt 只能工作到某个索引?

Why is ListView getChildAt working only upto certain index?

我有一个 ListViewCheckBoxTextView。我正在尝试使用索引查找 CheckBox。在我当前的测试场景中,我在 ListView 中有 16 个项目。以下代码一直工作到索引 5,然后给出 IllegalStateException。为什么会这样? 如何获得所有索引的 CheckBox 我相信这与 Layout 仅代表可见行有关。但即使我向下滚动,索引 0 也有效,而大于 5 的索引无效。 ListView 是 class 中的私有属性。代码:

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();
}

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

编辑:
您可能尝试做的是获取所有复选框的 isChecked() 值。问题是屏幕上的复选框永远不会多于可见的。所以 'all checkboxes' 永远不会全是 16。

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

通过您自己的适配器使用 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() 后,所有视图都将自动更改。