ListView和行回收问题 [英] ListView and rows recycling problem
问题描述
我有这样的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屋!