在 RecyclerView 中,如果希望更新列表数据时不让 Header 也刷新,可以通过以下方式处理:

  1. 使用 DiffUtil 进行局部刷新

    在 DiffUtil.Callback 中,通过 getItemViewType 区分 Header 和普通项,确保 Header 不会被重新绑定。
  2. 手动控制刷新范围

    在调用 notifyItemRangeChanged 或 notifyDataSetChanged 时,指定刷新的范围,跳过 Header 的位置。
  3. 使用 ConcatAdapter (如果支持)

    将 Header 和列表数据分开为两个 Adapter ,通过 ConcatAdapter 组合,这样更新列表数据时不会影响 Header 。

为了确保 Header 不刷新,我将修改这些调用,改为使用 notifyItemRangeChanged 并跳过 Header 的位置(即从位置1开始刷新)。

将 notifyDataSetChanged 替换为 notifyItemRangeChanged(1, commonAdapter.getItemCount() - 1) ,确保 Header (位置0)不会被刷新。

修改总结:

  1. 添加 getItemViewType 

    • 在 CommonRecycleViewAdapter 中添加了 getItemViewType 方法,用于区分 Header 和普通项。
  2. 修改刷新逻辑

    • 将 notifyDataSetChanged 替换为 notifyItemRangeChanged ,跳过 Header 的位置。

后续建议:

  • 如果 Header 的内容需要更新,可以单独调用 notifyItemChanged(0) 。
  • 确保 Header 的逻辑在 onBindViewHolder 中正确处理。

在 RecyclerView中避免Header随列表数据刷新而重新加载,可以通过以下几种方式实现,核心思路是将Header与普通列表项区分对待,确保刷新操作只影响内容区域:

1. 使用多类型布局(推荐)

通过getItemViewType()为Header和普通项设置不同类型,在onBindViewHolder()中仅处理普通项的刷新逻辑:

public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    private static final int TYPE_HEADER = 0;
    private static final int TYPE_ITEM = 1;
    
    private List<String> mData;
    private View mHeaderView;

    // 构造方法传入Header和数据
    public MyAdapter(View headerView, List<String> data) {
        mHeaderView = headerView;
        mData = data;
    }

    @Override
    public int getItemViewType(int position) {
        // 第一个位置是Header
        return position == 0 ? TYPE_HEADER : TYPE_ITEM;
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        if (viewType == TYPE_HEADER) {
            return new HeaderViewHolder(mHeaderView);
        } else {
            // 创建普通项ViewHolder
            View view = LayoutInflater.from(parent.getContext())
                   .inflate(R.layout.item_layout, parent, false);
            return new ItemViewHolder(view);
        }
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        // 只绑定普通项的数据,Header不处理
        if (holder instanceof ItemViewHolder) {
            String data = mData.get(position - 1); // 注意索引偏移
            ((ItemViewHolder) holder).bind(data);
        }
        // Header不执行绑定操作,避免刷新
    }

    @Override
    public int getItemCount() {
        return mData.size() + 1; // +1 是Header
    }

    // HeaderViewHolder仅持有View,不做数据绑定
    static class HeaderViewHolder extends RecyclerView.ViewHolder {
        HeaderViewHolder(View itemView) {
            super(itemView);
        }
    }

    // 普通项ViewHolder
    static class ItemViewHolder extends RecyclerView.ViewHolder {
        TextView textView;

        ItemViewHolder(View itemView) {
            super(itemView);
            textView = itemView.findViewById(R.id.text);
        }

        void bind(String data) {
            textView.setText(data);
        }
    }
}

2. 局部刷新而非全量刷新

更新数据时,使用notifyItemRangeChanged()指定刷新范围,跳过Header位置:


// 更新数据时,从索引1开始刷新(跳过Header)
public void updateData(List<String> newData) {
    mData.clear();
    mData.addAll(newData);
    // 从位置1开始刷新,刷新数量为数据大小
    notifyItemRangeChanged(1, mData.size());
}

3. 使用payload实现部分刷新

通过notifyItemChanged(int position, Object payload)传递 payload,在onBindViewHolder中根据payload判断是否需要刷新:

// 更新时传递payload
notifyItemChanged(position, "PARTIAL_REFRESH");

// 在onBindViewHolder中处理
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position, List<Object> payloads) {
    if (payloads.isEmpty()) {
        super.onBindViewHolder(holder, position, payloads);
    } else {
        // 只处理普通项的部分刷新
        if (holder instanceof ItemViewHolder) {
            // 执行局部刷新逻辑
        }
    }
}

4. 将Header作为RecyclerView的HeaderView(非标准方式)

通过给RecyclerView添加addHeaderView()(需自定义LayoutManager或使用第三方库如BaseRecyclerViewAdapterHelper),使Header脱离Adapter的刷新机制。

关键原理

  • Header的ViewHolder不执行bind操作,避免数据刷新时重绘
  • 刷新时精确控制范围,排除Header的位置(通常是position=0)
  • 利用getItemViewType将Header与普通项完全隔离

这种方式既能保证Header的稳定性,又能让列表内容正常刷新,适用于需要固定头部(如搜索框、筛选器)的场景。

Logo

葡萄城是专业的软件开发技术和低代码平台提供商,聚焦软件开发技术,以“赋能开发者”为使命,致力于通过表格控件、低代码和BI等各类软件开发工具和服务

更多推荐