当前位置: 首页 > 知识库问答 >
问题:

setTag 和 getTag 在 ViewHolder 模式中是如何工作的?

子车超英
2023-03-14

我有一个实现自定义listview的简单代码段。

我的代码如下:

天气适配器。爪哇语:

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);

    }
    }
}

我在so和其他网站上看到了这么多答案,我明白了listview的回收机制。

我还了解到,从 viewholder 那里,我们可以将子视图保存在适配器中,而不必多次调用 findViewById()。因此,这是为了优化。

但是我只有setTag(holder)getTag()方法中的混淆。通过这个问题,我了解到它是用于在多个对象上创建键值对,以便我们可以轻松访问它们。但是,我不明白为什么这里需要它们…因为我们没有多个holder对象…只是我们每次都要改变holder的变量。我们可以在这里编码而不使用<code>setTag</code>和<code>getTag

谁能更好地解释一下< code>setTag和< code>getTag在“这里”做什么?

共有3个答案

汤枫涟
2023-03-14

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

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

养昊天
2023-03-14

让我们从不同的角度来看:

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

当你切断“固定”的绳子时,直升机仍然在飞,但是飞行员不能再控制它了,因为飞行员掉在地上了,这意味着飞行员已经死了!(在java中,当一个对象丢失了它的引用时,垃圾收集器会收集它并从内存中释放)。

当直升机即将飞到飞行员坐的位置时,如果你没有将绳索系在车上,你可能会失去对直升机的控制,因为你使用的是“有线遥控”。

我希望这有助于:)。

巫煌
2023-03-14

标记是一种使您的视图记住某些内容的机制,可以是对象整数 字符串或任何您喜欢的内容。

因此,当您的ListView将首次创建您的convertView时,您的convertView。因此,您可以创建一个新的 convertView,并将该对象的所有引用都放在 viewHolder 中。然后将您的视图持有者保存到该转换视图(setTag)的内存中。Android会获取您的convertView并将其放入其中以回收它并再次将其传递给您。但它的可能没有足够的转换视图,因此它再次传递一个新的归零转换视图。所以这个故事再次重复,直到机器人的池子被填满。之后,Android从其池中获取转换视图并将其传递给您。你会发现它不是的,所以你问它我第一次给你的对象引用在哪里?(getTag),所以你会得到这些,做任何你喜欢的事情。

更多细节在下面一行

< code >但是它的池可能没有足够的convertView,所以它再次传递一个新的为null的convert view

当您的列表视图要创建时,android 是空的。因此,对于列表的第一项查看,它会向您发送必须显示的转换视图。之后,Android将其保存在其中,因此其现在仅包含一个convertView。对于您的列表的第二项创建Android的View不能使用其池,因为它实际上有一个元素,并且该元素是您的第一个项目,它现在正在显示,因此它必须通过另一个convertView。此过程将重复,直到android在其中找到现在未显示的convertView并将其传递给您。

Android膨胀每一行,直到屏幕填满之后,当你滚动列表它使用持有人。

 类似资料:
  • 问题内容: 这是我的ArrayAdapter。我想通过遵循ViewHolder模式来提高效率: http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/view/List14.html 但不确定如何做到这一点。 更新:ViewHolder模式 问题答案: ViewHolder本质上是一

  • 在ViewHolder模式中将ViewHolder作为静态对性能至关重要吗? ViewHolder对象将每个组件视图存储在布局的标签字段中,因此您可以立即访问它们,而不需要重复查找它们。首先,您需要创建一个类来保存您准确的视图集。例如:

  • 我正在研究RSA加密,并在C#中使用我的公钥。但我的公钥模数和指数为十进制格式,如下所示: 公众指数:65537 我如何在C#中使用上面的RSA加密?

  • 在Spark中是如何工作的? 如果我们注册一个对象作为一个表,会将所有数据保存在内存中吗?

  • 我从网上和论坛上看到了关于BatchSize的相关主题,但我仍然不明白一些部分。所以让我们描述一下我理解的和不理解的。 批量取数:选择取数的优化策略。Hibernate通过指定主键或外键列表,在一次选择中检索一批实体实例或集合。 让我们有JPA 2.0,带有Hibernate实现。这些实体: } 因此,我懒得去了解产品中的制造商。因此,当我执行select fetching时,就完成了。所以我有很

  • 我的项目中的三个模型对象(本文末尾的模型和存储库片段)之间确实存在关系。 当我调用时,它会触发三个select查询: (“sql”) (对我来说)那是相当不寻常的行为。在阅读Hibernate文档后,我认为它应该始终使用连接查询。当类中的更改为时,查询没有区别(使用附加选择进行查询),当更改为时,城市类的查询也一样(使用JOIN进行查询)。 当我使用抑制火灾时,有两种选择: 我的目标是在所有情况下