You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在List Adapter中需检查现有视图吗?附Expandable List Adapter代码

在Expandable List Adapter中检查现有视图的必要性

当然有必要!这是Android列表组件优化性能的核心操作之一,咱们来掰扯清楚为什么:

核心原因:视图复用机制

Android的ExpandableListView(包括普通ListView)为了避免大量创建视图导致内存过载、滚动卡顿,会回收滑出屏幕的视图,用来重新填充新滑入屏幕的条目内容。检查view == null就是为了判断当前是否有可复用的视图:

  • 当view == null时,说明没有可复用的视图,这时候才需要通过LayoutInflater加载布局文件,创建ViewHolder并绑定布局里的控件,最后用view.setTag(holder)把ViewHolder和视图绑定在一起;
  • 当view != null时,直接通过holder = (ViewHolder) view.getTag()取出之前绑定的ViewHolder,就能直接复用已有的控件引用,不用再重复执行findViewById和布局加载,大幅节省时间和内存。

不做检查的后果

如果跳过这个检查,每次都直接inflate新布局、创建新ViewHolder,会导致:

  • 内存占用飙升:比如列表有100条数据,屏幕只能显示10条,不复用的话会创建100个视图实例,而复用只需要10-12个;
  • 滚动卡顿:频繁的布局加载和对象创建会让列表滚动时出现明显掉帧,用户体验极差。

结合你的代码来看

你给出的代码片段是完全正确的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();
    // 这里记得更新holder里的mTrigger等数据,避免复用旧数据哦
}

唯一要注意的是,在复用ViewHolder的时候,一定要把新条目的数据更新到ViewHolder对应的控件里,不然会出现旧数据残留的问题(比如滑到下面的条目却显示上面条目的内容)。

内容的提问来源于stack exchange,提问作者Paxana Non Grata

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 07:37:35