我有一个可扩展的列表适配器。在其中我像这样膨胀视图
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();
}
我遇到的问题是,我对某个视图所做的更改有时会影响其他视图,但并不总是如此。当我拿出查看视图并且为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);
这似乎有效,但我总是学习检查if (view == null)
已存在的视图。有理由我不接受这个修复吗?是否存在内存泄漏或与此相关的任何内容?
答案 0 :(得分:1)
是的,它有很大的影响!我们检查和重用view
而不是创建它的原因是,每次getView()
调用方法都是为了节省大量内存。它被称为view
的回收,当有可供重用的视图时,Android会将其推送到getView()
方法,因为系统不会总是要重用views
,我们需要强制检查。下图将为您提供清晰的图片,并开始使用专为此回收目的而指定的RecyclerView
。
答案 1 :(得分:1)
我遇到的问题是,我对某个视图所做的更改有时会影响其他视图,但并不总是如此。
当您只修改视图的某个部分有时而不是始终时,通常会发生这种情况。例如,你可能有
if (position % 3 == 0) {
someView.setBackgroundColor(0xff0000ff);
}
如果您的视图被回收并稍后传递给getView()
(作为convertView
参数),它仍将具有蓝色背景。您应该编写代码以始终设置背景颜色:
if (position % 3 == 0) {
someView.setBackgroundColor(0xff0000ff);
} else {
someView.setBackgroundColor(0xffffffff);
}
我总是学会用if(view == null)检查已经存在的视图。我有理由不接受这个修复吗?
是的:给视图充气是昂贵且耗时的。如果您希望确保您的应用在用户提交列表时不丢弃任何帧,则应利用getView()
提供的回收功能。这不像是夸大一个视图是令人痛苦的慢,但如果你每次都膨胀一个新视图(因此每次都会使用很多findViewById()
个调用),你肯定会注意到滚动不如你跟随视图那么平滑持有人模式。