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

时间:2018-03-26 03:52:35

标签: java android layout-inflater android-viewholder

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

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)已存在的视图。有理由我不接受这个修复吗?是否存在内存泄漏或与此相关的任何内容?

2 个答案:

答案 0 :(得分:1)

是的,它有很大的影响!我们检查和重用view而不是创建它的原因是,每次getView()调用方法都是为了节省大量内存。它被称为view的回收,当有可供重用的视图时,Android会将其推送到getView()方法,因为系统不会总是要重用views,我们需要强制检查。下图将为您提供清晰的图片,并开始使用专为此回收目的而指定的RecyclerViewenter image description here

答案 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()个调用),你肯定会注意到滚动不如你跟随视图那么平滑持有人模式。