Android ViewHolder 模式中 setTag 和 getTag 的作用是什么?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25966689/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What is the working of setTag and getTag in ViewHolder pattern?
提问by xyz
I have a simple code snippet for implementing custom listview.
我有一个用于实现自定义列表视图的简单代码片段。
My code is as follows:
我的代码如下:
WeatherAdapter.java :
天气适配器.java :
public class WeatherAdapter extends ArrayAdapter<weather>{
Context mcontext;
int mlayoutResourceId;
weather mdata[] = null;
View row;
public WeatherAdapter(Context context, int layoutResourceId, weather[] data) {
super(context, layoutResourceId, data);
mlayoutResourceId = layoutResourceId;
mcontext = context;
mdata = data;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
row = convertView;
WeatherHolder holder = null;
if(row == null)
{
LayoutInflater inflater = ( (Activity) mcontext).getLayoutInflater();
row = inflater.inflate(mlayoutResourceId, parent, false);
holder = new WeatherHolder(row);
row.setTag(holder);
}
else
{
holder = (WeatherHolder)row.getTag();
}
weather w = mdata[position];
holder.txtTitle.setText(w.mtitle);
holder.imgIcon.setImageResource(w.micon);
return row;
}
WeatherHolder.java:
WeatherHolder.java:
class WeatherHolder
{
ImageView imgIcon;
TextView txtTitle;
public WeatherHolder(View v){
imgIcon = (ImageView)row.findViewById(R.id.imgIcon);
txtTitle = (TextView)row.findViewById(R.id.txtTitle);
}
}
}
I have seen so many answers on SO and other sites and I understood the recycling mechanism of listview.
我在 SO 和其他网站上看到了很多答案,我了解 listview 的回收机制。
I also understood that from viewholder, we can hold the child views in the adapter and we do not have to call findViewById()
many times. So, it is for optimization.
我也从viewholder了解到,我们可以在adapter中保存子视图,不需要findViewById()
多次调用。所以,这是为了优化。
But I have only the confusion in setTag(holder)
and getTag()
methods. From this question, I came to know that it is for making a key-value pair on multiple objects, so that we can access them easily. But, I do not understand why they are required here...because, we do not have multiple holder objects...only we have to change holder's variables each time. can we code here without using setTag
and getTag
?
但我只有混淆setTag(holder)
和getTag()
方法。从这个问题,我开始知道它是为了在多个对象上制作键值对,以便我们可以轻松访问它们。但是,我不明白为什么这里需要它们……因为,我们没有多个持有者对象……只有我们每次都必须更改持有者的变量。我们可以在这里编码而不使用setTag
andgetTag
吗?
can anyone explain better that what setTag
and getTag
do "here"?
谁能更好地解释“在这里”做什么setTag
和getTag
做什么?
回答by mmlooloo
tag
is a mechanism to make your views
remember something, that could be an object
an integer
a string
or anything you like.
tag
是一种机制,让您views
想起了什么,这可能是一个object
的integer
一个string
或任何你喜欢的。
so when your ListView
is going to create for the first time your convertView
is null
. so you create a new convertView
and put all of your references
of the objects
of that row
in a viewHolder
. then save your viewHolder
into the memory of that convertView
(setTag). Android
takes your convertView
and puts it in its pool
to recycle
it and passes
it again to you. but its pool
may not have enough convertViews
so it again passes a new convertView
thats null
. so again the story is repeated till the pool
of android
is filled up. after that android
takes a convertView
from its pool and passes it to you. you will find that its not null
so you ask it where are my object references
that I gave to you for the first time? (getTag) so you will get those and do whatever you like.
所以当你ListView
第一次创建你convertView
的null
. 所以你创建一个新的convertView
,并把所有的references
的objects
那row
一个viewHolder
。然后将您保存viewHolder
到内存中convertView
(setTag)。Android
拿走你的convertView
,把它放进pool
去recycle
,然后passes
再给你。但它pool
可能没有足够的convertViews
,因此再次通过新的convertView
多数民众赞成null
。如此反复重复的故事,直到pool
中android
被填满。之后从它的池中android
取出一个convertView
并将它传递给你。你会发现它不是null
所以你问它我的对象在哪里references
我第一次给你的?( getTag) 所以你会得到这些并做任何你喜欢的事情。
More elaboration on below line
下一行的更多详细说明
but its pool may not have enough convertViews so it again passes a new convertView thats null
but its pool may not have enough convertViews so it again passes a new convertView thats null
android pool
is empty when your listView
is going to create. so for the first item of your listView
it sends you a convertView
that must be displayed. after that android
saves it in its pool
, so its pool
now contains just one convertView
. for your second item of your listView
that is going to create android can not use its pool because it is actually has one element and that element is your first item and it is being shown right now so it has to pass another convertView
. this process repeates until android
found a convertView
in its pool
thats not being displayed now and passes it to you.
pool
当您listView
要创建时,android为空。因此,对于您的第一项,listView
它会向您发送一个convertView
必须显示的信息。之后android
将它保存在它的pool
,所以它pool
现在只包含一个convertView
. 对于您listView
将要创建的第二个项目,android 无法使用其池,因为它实际上有一个元素,而该元素是您的第一个项目,并且它现在正在显示,因此它必须通过另一个convertView
。这个过程会重复,直到在它现在没有显示的地方android
找到一个并将它传递给你。convertView
pool
Android inflates each row till the screen filled up after that when you scroll the list it uses holder.
当您滚动列表时,Android 会膨胀每一行,直到屏幕填满为止。
回答by neferpitou
Lets Look in a Different Perspective:
让我们换个角度看:
Lets imagine that the Helicopteris the "row" while the ropeis the "setTag" and the carbelow is "WeatherHolder", but the pilot of the Helicopter is inside that car and he/she the one managing controlling the helicopter using a "WIRED REMOTE".
让我们想象一下直升机是“排”,而绳子是“ setTag”,下面的车是“ WeatherHolder”,但是直升机的飞行员在那辆车里,他/她是使用“控制直升机的人”有线遥控器”。
When you cut the Rope Which is "setTag" the Hellicopter still fly but the pilot can no longer control it since the pilot is drop in the ground which means the pilot is now dead! (In java when an object loss its reference the Garbage Collector will collect that and free from the memory).
当你切断“setTag”的绳子时,直升机仍然飞行,但飞行员无法再控制它,因为飞行员掉在地上,这意味着飞行员现在已经死了!(在 Java 中,当对象丢失其引用时,垃圾收集器将收集该对象并从内存中释放)。
When you did not place or attach the rope to the car while the Helicopter is about to fly where the Pilot is sitting - you potentially loss a control on the helicopter because you are using "WIRED REMOTE".
如果在直升机即将飞到飞行员所在的位置时您没有将绳索放置或连接到汽车上 - 您可能会失去对直升机的控制,因为您使用的是“有线遥控”。
I hope this help :).
我希望这会有所帮助:)。
回答by Andrew Breen
But, I do not understand why they are required here...because, we do not have multiple holder objects
但是,我不明白为什么这里需要它们......因为,我们没有多个持有者对象
This is where you are wrong - there is one holder per view (aka visible or cached ListView entry).
这就是你错的地方——每个视图有一个持有者(也就是可见或缓存的 ListView 条目)。