我尝试使用ListView
创建ArrayAdapter<T>
,其中T
类型作为视图持有者第二次使用。这可能看起来有点奇怪,但这背后的想法是我可以编写一个onClick(View view)
方法,该方法以view.getTag()
行开头,直接转到T
View
的实例public class MyActivity extends Activity {
private static final class ViewHolder {
private final String string;
private TextView textView;
private ViewHolder(String string) {
this.string = string;
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
final List<ViewHolder> viewHolders = new ArrayList<ViewHolder>();
for (int i = 0; i < 20; i++) {
viewHolders.add(new ViewHolder("A"));
viewHolders.add(new ViewHolder("B"));
viewHolders.add(new ViewHolder("C"));
}
final ArrayAdapter<ViewHolder> adapter = new ArrayAdapter<ViewHolder>(this, -1, viewHolders) {
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view;
TextView textView;
if (convertView == null) {
view = getLayoutInflater().inflate(R.layout.item_layout, parent, false);
textView = (TextView) view.findViewById(R.id.text_view);
} else {
view = convertView;
textView = ((ViewHolder) convertView.getTag()).textView;
}
ViewHolder viewHolder = viewHolders.get(position);
textView.setText(viewHolder.string);
viewHolder.textView = textView;
view.setTag(viewHolder);
return view;
}
};
((ListView) findViewById(R.id.list_view)).setAdapter(adapter);
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Collections.rotate(viewHolders, 1);
adapter.notifyDataSetChanged();
}
});
}
}
1}}是从。
这是代码。
convertView
我无法理解为什么这不起作用。在这两种情况下(null
是或不是View
),您始终会返回包含TextView
的{{1}},其中文本已设置为viewHolders.get(position).string
}。当然,尽管这种方法很复杂,但您应该始终看到A
,B
,C
,A
,B
,C
等? ViewHolder
有60个不同的实例,你在屏幕上的两个地方永远不会有相同的TextView
,因为你传递的convertView
应该来自屏幕外的位置?我明显错了,因为点击旋转几次之后订单就会搞砸了。如果有人能向我解释,我真的很感激。
以下是activity_my.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:id="@+id/button"
android:paddingBottom="5dp"
android:paddingTop="5dp"
android:text="Rotate"
android:textSize="24sp"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<ListView
android:id="@+id/list_view"
android:layout_width="match_parent"
android:layout_height="match_parent">
</ListView>
</LinearLayout>
以下是item_layout.xml
。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/text_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="5dp"
android:paddingBottom="5dp"
android:textSize="24sp"
android:gravity="center"
/>
</LinearLayout>
答案 0 :(得分:0)
这非常令人困惑,但我想我已经弄清楚这是怎么发生的。
第1步:为getView
ViewHolder
调用h
,并返回View
v
。
现在v.getTag() == h
和h.textView
是TextView
中的v
。
第2步:为同一getView
ViewHolder
调用h
,但这次会返回不同的View
w
。
此时w.getTag() == h
和h.textView
已更改为TextView
中的w
。
第3步:调用getView
,convertView
使用的是v
。
此时v.getTag()
仍然是h
从步骤1开始,但h.textView
已更改为步骤2中TextView
中的w
。这意味着行textView.setText(viewHolder.string);
实际上并未将文本设置为正确的TextView
。