Android 为什么ListView getChildAt只能在特定索引下工作?

Android 为什么ListView getChildAt只能在特定索引下工作?,android,android-layout,android-listview,android-linearlayout,Android,Android Layout,Android Listview,Android Linearlayout,我有一个带有复选框的列表视图和文本视图。我正在尝试使用索引查找复选框。在我当前的测试场景中,ListView中有16项。下面的代码一直工作到索引5,并在索引5之后给出IllegalStateException。为什么会这样如何获取所有索引的复选框?我相信这与布局仅表示可见行有关。但即使我向下滚动,索引0仍然有效,而大于5的索引则无效列表视图是类中的私有属性。代码: public void inform(View v) { TextView tv;

我有一个带有
复选框的
列表视图
文本视图
。我正在尝试使用索引查找
复选框
。在我当前的测试场景中,
ListView
中有16项。下面的代码一直工作到索引5,并在索引5之后给出
IllegalStateException
。为什么会这样如何获取所有索引的
复选框
我相信这与
布局
仅表示可见行有关。但即使我向下滚动,索引0仍然有效,而大于5的索引则无效<代码>列表视图
是类中的私有属性。代码:

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()值。问题是,屏幕上显示的复选框最多。所以“所有复选框”永远都不是16


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

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

编辑:
您可能会尝试获取所有复选框的isChecked()值。问题是,屏幕上显示的复选框最多。所以“所有复选框”永远都不是16


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

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

编辑:
您可能会尝试获取所有复选框的isChecked()值。问题是,屏幕上显示的复选框最多。所以“所有复选框”永远都不是16


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

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

编辑:
您可能会尝试获取所有复选框的isChecked()值。问题是,屏幕上显示的复选框最多。所以“所有复选框”永远都不是16


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

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

公共类SamdCapter扩展BaseAdapter{
List mData;//不要忘记实例化这个
@凌驾
public int getCount(){
返回mData.size();
}
@凌驾
公共对象getItem(int位置){
返回mData.get(位置);
}
public void setIsChecked(布尔值isChecked){
用于(项目:mData){
item.isChecked=isChecked;
}
notifyDataSetChanged();
}
@凌驾
公共长getItemId(int位置){
返回0;
}
@凌驾
公共视图getView(int位置、视图转换视图、视图组父视图){
//一些例子。在这里创建或膨胀视图
if(convertView==null)
convertView=new复选框(parent.getContext());
convertView.isChecked(mData.isChecked);
返回视图;
}
}
已更新


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

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

公共类SamdCapter扩展BaseAdapter{
List mData;//不要忘记实例化这个
@凌驾
public int getCount(){
返回mData.size();
}
@凌驾
公共对象getItem(int位置){
返回mData.get(位置);
}
public void setIsChecked(布尔值isChecked){
用于(项目:mData){
item.isChecked=isChecked;
}
notifyDataSetChanged();
}
@凌驾
公共长getItemId(int位置){
返回0;
}
@凌驾
公共视图getView(int位置、视图转换视图、视图组父视图){
//一些例子。在这里创建或膨胀视图
if(convertView==null)
convertView=new复选框(parent.getContext());
convertView.isChecked(mData.isChecked);
返回视图;
}
}
已更新


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

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

公共类SamdCapter扩展BaseAdapter{
List mData;//不要忘记实例化这个
@凌驾
public int getCount(){
返回mData.size();
}
@凌驾
公共对象getItem(int位置){
返回mData.get(位置);
}
public void setIsChecked(布尔值isChecked){
F
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 ;
}
}