Java 使用视图持有者时,listView中的行循环是如何工作的?
我为我的ListView行定义了一个ViewHolder,如下所示:Java 使用视图持有者时,listView中的行循环是如何工作的?,java,android,listview,android-viewholder,Java,Android,Listview,Android Viewholder,我为我的ListView行定义了一个ViewHolder,如下所示: 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.findViewByI
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);
}
}
@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);
}
适配器类的getView()
方法如下所示:
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);
}
}
@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);
}
现在我的问题是:
getTag()
调用将返回nullrow.setTag(holder)
做什么?它如何重新初始化ViewHoldergetTag()
和setTag()
如何帮助我们我对工作机制有点困惑,搜索堆栈溢出时没有找到任何结果。这是一个很好的问题。因此,为了了解适配器中标记的行为,我们需要了解listView中回收流程的实际行为
标记
是一个小工具,它可以让我们的视图
记住一些东西,可以是对象、整数或其他任何东西,因此当我们的列表视图
第一次开始创建时转换视图
为空值
,因此,我们创建一个新的convertView
,并将行
对象
的所有引用放在viewHolder
中,然后将viewHolder
保存到该convertView
的内存中(setTag
)。Android将我们的convertView
放入其池内存中进行回收,然后再次将其传递给我们。但是它的池内存可能没有足够的convertView
,因此它再次传递一个新的convertView
,它的null
。因此,这个故事再次被重复,直到android的池被填满。之后,android从其池中获取一个convertView
,并将其传递给我们。你会发现它不是空的,所以你会问它我第一次使用getTag()
给你的对象引用在哪里,这样你就可以得到它们并做任何你喜欢的事情
这是list ViewHolder的处理流程,但如果您想了解更多关于setTag()和getTag()的信息,我将给您一个示例:
假设您正在创建一组具有类似行为的视图,如:
button1.setOnClickListener(new OnClickListener ... );
button2.setOnClickListener(new OnClickListener ... );
然后您将重写方法onClick(),如下所示:
这是因为在onclick()
方法中只获得一个参数视图,您可以使用setTag()来更改其行为,使用值“0”和“1”访问不同的按钮:
加上
现在,通过使用函数getTag()将标记附加到视图,可以对每个按钮使用相同的OnClickListener:
这是因为您正在使用
setTag()
方法将视图放入池内存,然后相应地从池中获取这些视图。谢谢您,解释得很好,只是有一个疑问,在第二个问题中,我是否必须将同一个侦听器连接到两个按钮?我认为这仅在这种情况下有效。是的,相同的侦听器将适用于两个按钮。只是出于好奇,您使用具有viewholder模式的ListView而不是RecyclerView有什么原因吗?@SpaceBison由于ListView未被弃用,我在我的应用程序中使用了它
listener = new OnClickListener() {
@Override
public void onClick(View view) {
doAction(view.getTag());
}
};