在列表适配器中是否有我应该检查现有视图的原因?
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 滚动而不是跟随视图持有者模式。
我有一个可扩展列表适配器。在其中我像这样膨胀视图
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 滚动而不是跟随视图持有者模式。