13

I have a simple code snippet for implementing custom listview.

My code is as follows:

WeatherAdapter.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:

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.

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.

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?

can anyone explain better that what setTag and getTag do "here"?

4

3 回答 3

27

tag是一种让你views记住某些东西的机制,它可以是object一个integerastring或任何你喜欢的东西。

因此,当您ListView第一次要创建时,您convertView就是null. 所以你创建一个新的convertView并将你所有的references放在一个. 然后将您保存到那个(setTag)的内存中。拿走你的,把它放进去,然后再给你。但它可能还不够,所以它再次通过了一个新的多数民众赞成。所以故事再次重复,直到填满。之后从它的池中取出 a并将其传递给您。你会发现它不是所以你问它我的对象在哪里objectsrowviewHolderviewHolderconvertViewAndroidconvertViewpoolrecyclepassespoolconvertViewsconvertViewnullpoolandroidandroidconvertViewnullreferences我第一次给你的?( getTag ) 所以你会得到这些并做任何你喜欢的事情。

在下面的行中进行更多详细说明

but its pool may not have enough convertViews so it again passes a new convertView thats null

当你要创建时, androidpool是空的。listView因此,对于您的第一项,listView它会向您发送一个convertView必须显示的内容。之后android将其保存在其中pool,因此它pool现在只包含一个convertView。对于您listView要创建的第二项 android 不能使用它的池,因为它实际上有一个元素,而该元素是您的第一项,并且它现在正在显示,所以它必须传递另一个convertView。此过程重复进行,直到在其中android找到现在未显示的内容并将其传递给您。convertViewpool

当您滚动它使用的列表时,Android 会膨胀每一行,直到屏幕填满。

于 2014-09-22T04:56:49.727 回答
18

让我们换个角度看:

在此处输入图像描述

让我们想象直升机是“”,而绳索是“ setTag ”,下面的汽车是“ WeatherHolder ”,但直升机的飞行员在那辆车内,他/她使用“有线遥控器”。

当您切断“setTag”的绳索时,直升机仍然飞行,但飞行员无法再控制它,因为飞行员掉在地上,这意味着飞行员现在已经死了!(在java中,当一个对象丢失它的引用时,垃圾收集器将收集它并从内存中释放出来)。

如果您在直升机即将飞到飞行员所在的位置时没有将绳索放置或连接到汽车上 - 您可能会失去对直升机的控制,因为您正在使用“有线遥控器”。

我希望这会有所帮助:)。

于 2015-01-21T03:46:39.170 回答
2

但是,我不明白为什么这里需要它们……因为我们没有多个持有者对象

这是你错的地方 - 每个视图都有一个持有者(也就是可见或缓存的 ListView 条目)。

于 2014-09-22T04:27:21.117 回答