我为ListView行定义了一个ViewHolder,如下所示:
->joinField('qty','cataloginventory/stock_item','qty','product_id=entity_id','{{table}}.is_in_stock=1','left')
并且适配器类的import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
class ViewHolder
{
ImageView icon=null;
TextView size=null;
ViewHolder(View row)
{
this.icon=(ImageView)row.findViewById(R.id.icon);
this.size=(TextView)row.findViewById(R.id.size);
}
}
方法如下所示:
getView()
现在我的问题是:
在@Override
public View getView(int position, View convertView,
ViewGroup parent) {
View row=super.getView(position, convertView, parent);
ViewHolder holder=(ViewHolder)row.getTag();
if (holder==null) {
holder=new ViewHolder(row);
row.setTag(holder);
}
if (getModel(position).length()>4) {
holder.icon.setImageResource(R.drawable.delete);
}
else {
holder.icon.setImageResource(R.drawable.ok);
}
holder.size.setText(String.format(getString(R.string.size_template), items[position].length()));
return(row);
}
调用View的情况下,在什么情况下会返回null?
getTag()
做了什么以及如何重新初始化ViewHolder?
如何在ListView中回收视图,以及row.setTag(holder)
和getTag()
在使用适配器时如何帮助我们?
我对工作机制有点困惑,并且在没有找到任何结果的情况下搜索了Stack Overflow。
答案 0 :(得分:1)
这是一个非常好的问题。为了了解适配器中Tags的行为,我们需要知道listView中循环过程流的实际行为。
Tag
是一个小工具,可让我们的views
记住一些东西,可能是一个对象,一个整数或其他任何东西,所以当我们的ListView
第一次创建时该时间convertView
为null
,因此我们创建了一个新的convertView
,并将row
objects
的所有引用放在viewHolder
中,然后将viewHolder
保存到convertView
(setTag
)的内存中。 Android接受我们的convertView
并将其放入池内存中以回收它并将其再次传递给我们。但是它的池内存可能不够convertViews
,因此它再次传递convertView
null
。所以故事再次重复,直到android池充满为止。之后android
从其池中获取convertView
并将其传递给我们。你会发现它不是null,所以你问它我第一次使用getTag()
给你的对象引用在哪里,这样你就可以得到那些并做你喜欢的事。
这是列表ViewHolder的流程,但如果你想了解更多关于setTag()和getTag()的信息,我会给你一个例子:
假设您正在创建具有类似行为的一堆视图,如:
button1.setOnClickListener(new OnClickListener ... );
button2.setOnClickListener(new OnClickListener ... );
然后你将覆盖方法onClick(),如:
private void onClick(View view) {
doAction(0); // here 0 for button 1 and 1 for button 2.
}
这是因为在onclick()
方法中只有一个参数View,你可以使用setTag()来改变它的行为,使用值'0'和'1'来访问不同的按钮:
只需添加
button1.setTag(0);
button2.setTag(1);
现在,您可以通过使用函数getTag()获取附加到View的标记,为每个按钮使用相同的OnClickListener:
listener = new OnClickListener() {
@Override
public void onClick(View view) {
doAction(view.getTag());
}
};
这是因为您使用setTag()
方法将视图放入池内存中,然后相应地从池中获取这些视图。