我开发了一个非常简单的应用程序,它为ListView使用自定义适配器。
每行有两个TextView:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView android:id="@+id/text1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView android:id="@+id/text2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
android:visibility="gone" />
</LinearLayout>
第一个TextView名为“text1”,第二个名称为“text2”。 如您所见, text2被隐藏(visibility =“gone”)。
此外,该列表的标题只包含EditText小部件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<EditText android:layout_width="fill_parent"
android:layout_height="wrap_content" />
</LinearLayout>
每一行都由一个名为“Item”的非常简单的对象表示,该对象具有2个属性(text1和text2)及其getter / setter。此外,它有一个“hasText2”方法,只检查对象是否具有text2属性值的长度&gt; 0:
public class Item {
private String text1;
private String text2;
public String getText1() {
return text1;
}
public void setText1(String text1) {
this.text1 = text1;
}
public boolean hasText2() {
return text2.length() > 0;
}
public String getText2() {
return text2;
}
public void setText2(String text2) {
this.text2 = text2;
}
}
好的,我将在主应用程序文件中仅使用2个项目初始化列表:
Item item1 = new Item();
item1.setText1("Item 1");
item1.setText2("optional 1");
Item item2 = new Item();
item2.setText1("Item 2");
item2.setText2("");
getListView().addHeaderView(getLayoutInflater().inflate(R.layout.list_header, null), false, false);
m_items = new ArrayList<Item>();
m_adapter = new CustomListAdapter(this, R.layout.list_row, m_items);
setListAdapter(m_adapter);
m_items.add(item1);
m_items.add(item2);
m_adapter.notifyDataSetChanged();
这是我的自定义适配器的getView方法(扩展了ArrayAdapter):
@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);
}
// get the two text widgets of this row layout
TextView text1 = (TextView) convertView.findViewById(R.id.text1);
TextView text2 = (TextView) convertView.findViewById(R.id.text2);
// get the Item object of this row
Item list_item = items.get(position);
// we set the text1 property of this Item to the text1 widget
text1.setText(list_item.getText1());
// if this Item has a text2 (value length > 0), then set it to the text2 widget and make it visible
if (list_item.hasText2()) {
text2.setText(list_item.getText2());
text2.setVisibility(0);
}
return convertView;
}
所以,我想要的是仅当Item对象定义了它时才显示text2小部件(值的长度> 0)。
这是运行应用程序后的结果:
这很好,它的工作方式与我预期的一样! :)
但是,如果我点击列表标题的EditText怎么办? (所以我强制更新列表):
这里发生了什么?这不可能。第二行没有定义text2,Android刚刚从第一行获取了text2!为什么?
我能想象的唯一原因是我无法使用具有不同可见性的行......但是,为什么Android让我在运行应用程序时执行此操作?它似乎仅在键盘出现时失败(列表更新)。
答案 0 :(得分:2)
这有一个问题,原因与我在前一个问题的笔记中描述的完全相同。视图正在被回收,因此在if (list_item.hasText2()) {
子句中执行的自定义将永久设置在该视图上;即使再循环到一个不适合该条款的观点。
在这种情况下,以下修改可能会解决问题:
if (list_item.hasText2()) {
text2.setText(list_item.getText2());
text2.setVisibility(View.VISIBLE);
} else {
text2.setVisibility(View.GONE);
}