ListView和行回收问题

时间:2011-04-23 20:59:35

标签: android

我有这个ListView:

enter image description here

我正在使用自定义适配器。

如您所见,每行都由一个复选框,一个大TextView和一个TextView组成。 所有项目都定义了小TextView,甚至是“Item 2”,但它是一个空字符串。

当我点击列表标题中的EditText时出现问题:

enter image description here

键盘出现,行被回收,因此调用了我的适配器的getView方法。在那个方法中,我有一个if子句,我检查“可选”文本(小TextView)的长度是否大于0.在这种情况下,我做了一些空间(你可以在屏幕截图中看到的空间)和我显示它。

问题是“第2项”已初始化“可选”文本,但它是无效的(0大小)。我不明白为什么执行if子句。但更奇怪的是......其他的也被执行了!在else中我只是在TextView中显示一个void字符串。

为什么会这样?该应用程序非常简单。这是我的getView方法:

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    if (convertView == null) {
        LayoutInflater vi = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        convertView = vi.inflate(R.layout.list_row, null);
    }

    ListItem list_item = items.get(position);

    TextView item_title = (TextView) convertView.findViewById(R.id.item_title);
    TextView item_optional = (TextView) convertView.findViewById(R.id.item_optional);

    item_title.setText(list_item.getTitle());

    // If the task has an optional text, make some room and display it
    if (list_item.hasOptional()) {
        // This portion of code will be executed when you tap the EditText and the keyboard appears, putting the item up in the row
        LayoutParams layout_params = (LayoutParams) item_title.getLayoutParams();
        layout_params.topMargin = 10;
        layout_params.height = -2;  // -2: wrap_content
        item_title.setLayoutParams(layout_params);
        item_optional.setText(list_item.getOptional());
        item_optional.setVisibility(0);
    } else {
        // This portion of code will ALSO be executed when you tap the EditText... why? this should not happen!
        item_optional.setText("");
    }

    return convertView;
}

可以看到源代码here(github)。

1 个答案:

答案 0 :(得分:2)

当您修改循环视图时,您不知道视图的状态,以及之前调用getView可能如何自定义视图的状态。您正在回收的视图 R.layout.list_row的新开箱即用通货膨胀。将其视为“二手”或“二手”视图。

因此,我可以在if (list_item.hasOptional()..下看到您对item_title.getLayoutParams()进行了一些修改。由于此处创建的视图以后可能会被回收用于未通过if (list_item.hasOptional()代码块下的检查else的列表项,因此必须将修改后的值重置为布局中指定的默认值。