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

问题描述 投票:1回答:2

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

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

java android layout-inflater android-viewholder
2个回答
1
投票

我遇到的问题是,我对某个视图所做的更改有时会影响其他视图,但并不总是如此。

当您仅修改视图的一部分时,通常会发生这种情况,而不是始终。例如,你可能有

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

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

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

我总是学会用if(view == null)检查已经存在的视图。有理由我不接受这个修复吗?

是的:给视图充气是昂贵且耗时的。如果您想确保您的应用在用户甩尾时不丢弃任何帧,您应该利用getView()提供的回收功能。这并不像膨胀一个视图是令人痛苦的慢,但如果你每次都膨胀一个新的视图(因此每次都使用大量的findViewById()调用),你肯定会注意到比你遵循视图持有者模式更不平滑的滚动。


1
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.