ListView和行回收问题 [英] ListView and rows recycling problem

查看:103
本文介绍了ListView和行回收问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这样的ListView:

I have this ListView:

我使用的是自定义适配器。

I'm using a custom adapter.

正如你所见,每一行是由一个复选框,一个大TextView的,和一点点的TextView的。
所有项目已经定义了小的TextView,连项目2,但它是一个空字符串。

As you see, each row is made of a checkbox, a big TextView, and a little TextView. All items have defined the little TextView, even the "Item 2" but it's a void string.

问题是当我点击放置在列表的标题中的EditText:

The problem comes when I tap the EditText placed in the header of the list:

键盘显示,行被回收,所以我的适配器的getView方法被调用。在该方法中我有一个条款,如果我在那里检查,如果可选的文字(小的TextView)的长度大于0。在这种情况下,我做一些空间(您可以在截图中看到的空间)和我显示它。

The keyboard appears, and the rows are recycled, so the getView method of my adapter is called. In that method I have an if clause where I check if the length of the "optional" text (the little TextView) is greater than 0. In that case I make some room (the space that you can see in the screenshot) and I display it.

的问题是,项目2具有初始化可选的文字,但它是空隙(0尺寸)。为什么执行条款,如果我不明白。但更奇怪的是......也执行了别的!在别的我只是显示在小TextView中一个无效的字符串。

The problem is that "Item 2" has the "optional" text initialized but it's void (0-sized). I don't understand why the if clause is executed. But more strangely... the else is also executed! In the else I just show a void string in the little TextView.

这是怎么回事?该应用程序是非常简单的。这是我的getView方法:

Why is this happening? The app is really simple. This is my getView method:

@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;
}

源$ C ​​$ C可以看出 这里 (github上)

The source code can be seen here (github).

推荐答案

当你修改回收视图,你不知道什么视图的状态,相对于它如何可能已被previous来电定做到 getView 。您正在回收的观点是的 R.layout.list_row的新出的现成的通货膨胀。把它看成是拿来主义是二手或视图。

When you modify a recycled view you have no idea what the state of the view is, with respect to how it might have been customized by previous calls to getView. The view you are recycling is not a fresh-out-the-box inflation of R.layout.list_row. Think of it as a "second hand" or "used" view.

所以我可以在看(list_item.hasOptional().. 你做一些修改的 item_title.getLayoutParams()。作为在这里创建的视图以后可能会被回收列表项目,将无法通过检查如果(list_item.hasOptional()其他 code座,你必须重新修改,以在布局中指定的默认​​值。

So I can see under if (list_item.hasOptional().. you make some modification to the item_title.getLayoutParams(). As a view created here may later be recycled for a list item that will fail the check if (list_item.hasOptional() under the else code block you must reset the values you modify to the default specified in the layout.

这篇关于ListView和行回收问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆