在列表适配器中是否有我应该检查现有视图的原因?

In a list adapter is there a reason i should check for existing view?

我有一个可扩展列表适配器。在其中我像这样膨胀视图

if (view == null) {

    view = LayoutInflater.from(mContext).inflate(R.layout.trigger_list_item, null);

    holder = new ViewHolder();
    holder.mTrigger = trigger;
    holder.triggerName = view.findViewById(R.id.triggerName);
    holder.upButton = view.findViewById(R.id.mTriggerButtonUp);
    holder.downButton = view.findViewById(R.id.mTriggerButtonDown);
    holder.total = view.findViewById(R.id.triggerCounter);

    view.setTag(holder);
}
else {
    holder = (ViewHolder) view.getTag();
}

我遇到了一个问题,我对一个视图所做的更改有时会影响其他视图,但并非总是如此。当我把 view 和 null 的check 拿出来时,它起作用了,留下这个。

view = LayoutInflater.from(mContext).inflate(R.layout.trigger_list_item, null);

holder = new ViewHolder();
holder.mTrigger = trigger;
holder.triggerName = view.findViewById(R.id.triggerName);
holder.upButton = view.findViewById(R.id.mTriggerButtonUp);
holder.downButton = view.findViewById(R.id.mTriggerButtonDown);
holder.total = view.findViewById(R.id.triggerCounter);

view.setTag(holder);

这似乎可行,但我一直学会用 if (view == null) 检查已经存在的视图。我有理由不接受这个修复吗?是否存在内存泄漏或与此相关的任何问题?

是的,效果非常好!我们检查并重用 view 而不是创建它的原因是每次调用 getView() 是为了节省大量内存。这叫做 view 的回收,只要有视图可以重用,Android 就会将其推送到 getView() 方法,因为系统不会总是有 views 可以重用,我们需要强制检查。下图将为您提供清晰的画面,并开始使用专门为此目的指定的 RecyclerView 进行回收。

I was having an issue where a change i made to one view would sometimes, though not always, effect others.

这通常发生在您只修改视图的一部分时有时,而不是总是。例如,您可能

if (position % 3 == 0) {
    someView.setBackgroundColor(0xff0000ff);
}

如果您的视图被回收并稍后传递给 getView()(作为 convertView 参数),它仍将具有蓝色背景。您应该改为编写代码以始终设置背景颜色:

if (position % 3 == 0) {
    someView.setBackgroundColor(0xff0000ff);
} else {
    someView.setBackgroundColor(0xffffffff);
}

I had always learned to check for the view already existing with if (view == null). Is there a reason I shouldn't accept this fix?

是的:膨胀视图很昂贵,而且 time-consuming。如果您想确保您的应用程序在用户浏览您的列表时不会丢失任何帧,您应该利用 getView() 提供的回收功能。这不像膨胀视图慢得令人痛苦,但如果你每次都膨胀一个新视图(因此每次也使用大量 findViewById() 调用),你肯定会注意到 less-smooth 滚动而不是跟随视图持有者模式。