我有一个ListView,我添加了一个标题(带有getListView(。addHeaderView),它只包含一个TextEdit小部件。
然后当我点击TextEdit开始写入时,键盘出现并且它弄乱了列表!
如果我点击其他地方隐藏键盘,列表会再次混乱!
我不知道为什么会这样。我认为它与onConfigurationChanged方法有关,但在实现它之后(并在清单文件中添加相应的属性)问题仍然存在。
我该如何解决?为什么Android搞砸我的名单?
修改
我的列表使用自定义适配器,这是getView方法:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v != null) {
return v;
}
LayoutInflater vi = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.list_row, null);
ListTask list_item = items.get(position);
if (list_item != null) {
TextView item_name = (TextView) v.findViewById(R.id.item_name);
item_name.setText(list_item.getTitle());
}
return v;
}
问题不是我的物品的价值,而是他们的订单。当键盘出现时,它们以不同的顺序显示,但值是正确的。
EDIT2:
好的,我已经用rekaszeru的建议改变了我的getView方法,现在它按预期工作了。但是现在我面临另一个问题:如果我的项目有两个文本视图怎么办?
假设第二个textview是可选的,“Item 1”和“Item 3”拥有它,但是“Item 2”没有,所以它被初始化为void String(length == 0)。 第一次显示列表时,它显示带有第二个文本视图的“Item1”和“Item 3”,以及没有它的“Item 2”。那是对的。但是当键盘出现时,“Item 2”将获取另一个项目的第二个textview并显示它!
这是我现在修改过的代码:
@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);
}
ListTask list_item = items.get(position);
TextView item_name = (TextView) convertView.findViewById(R.id.item_name);
TextView item_optional_text = (TextView) convertView.findViewById(R.id.item_optional_text);
item_name.setText(list_item.getTitle());
// if the item has defined the optional text, make some room and display it
if (item_optional_text.isNotEmpty()) {
LayoutParams layout_params = (LayoutParams) item_name.getLayoutParams();
layout_params.topMargin = 10;
layout_params.height = -2; // -2: wrap_content
item_name.setLayoutParams(layout_params);
item_optional_text.setText(list_item.getOptionalText());
}
return convertView;
}
isNotEmpty()在Item类中执行此操作:
public boolean isNotEmpty() {
return this.optional_text.length() > 0;
}
在书面问题中理解它可能太复杂了。如果是这样,我可以制作一个简短的视频来展示问题和我的源代码。在此先感谢您的帮助。
答案 0 :(得分:2)
你的行回收搞砸了。 Android没有改变项目的顺序,你是。
现在,如果您传递一行进行回收,则无需修改即可将其返回。这是个错误。您应该修改行的内容以反映所提供位置的数据。在这种情况下,您可以跳过的唯一逻辑是膨胀一个全新的行。
Here is a free excerpt来自我的一本经历过所有这些内容的书。
答案 1 :(得分:0)
您应该覆盖getView
实现中的ListAdapter
方法,并确保始终为要返回的视图分配新值(或者至少始终更新它以包含正确的数据)。
@Override
public View getView(int position, View convertView, ViewGroup parent)
{
convertView = inflater.inflate(R.layout.list_row, parent, false);
//set the necessary data in your TextViews, Checkboxes, etc...
return convertView;
}
如果您没有给项目渲染器充气,那么您可以从代码中实例化它,例如:
@Override
public View getView(int position, View convertView, ViewGroup parent)
{
convertView = new TextView([...]);
convertView.setText(textBasedOnYourData);
return convertView;
}
修改强>
正如@CommonsWare所指出的那样,应该注意回收列表项呈示器。因此,不应每次都实例化它,而应检查它是否已经存在,然后更新基础TextView
。
所以我建议尝试稍微修改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);
}
ListTask list_item = items.get(position);
TextView item_name = (TextView) convertView.findViewById(R.id.item_name);
//the item should never be null, but just in case:
item_name.setText((list_item == null) ? "" : list_item.getTitle());
return convertView;
}