如何自定义RecyclerView控件中显示条目的ID值
RecyclerView是否支持为条目设置自定义ID
完全支持,不需要受系统自动生成ID的限制,按照以下步骤配置即可生效:
具体实现步骤
- 第一步:开启稳定ID支持
在你的RecyclerView.Adapter的构造方法中调用setHasStableIds(true),这是自定义ID生效的前置条件,不开启的话系统会忽略你重写的ID返回值,始终使用自动生成的临时条目ID。 - 第二步:重写ID获取方法
重写Adapter中的getItemId(int position)方法,在方法内返回当前position对应条目的自定义业务ID即可,注意返回值必须是long类型。
注意事项
- 自定义ID必须保证在当前Adapter的全量数据中唯一,禁止两个不同的数据条目返回相同ID,否则会出现条目复用错乱、状态错位、动画异常、焦点丢失等问题
- 自定义ID需要和具体数据实体绑定,不要直接把列表position作为ID返回——如果列表存在插入、删除、排序移动操作,同一个数据实体的position会发生变化,会导致ID匹配失效;只要数据实体不变,它对应的自定义ID就不能变
- 不要返回
-1作为自定义ID,-1是系统定义的RecyclerView.NO_ID常量,代表无有效ID,会被系统特殊处理 - 不需要额外手动调用
itemView.setId()修改条目根布局ID,RecyclerView内部会自动使用getItemId()返回的值做条目追踪、状态保存、动画匹配,覆盖自动生成的默认ID。
代码示例
public class CustomListAdapter extends RecyclerView.Adapter<CustomListAdapter.ItemViewHolder> { private final List<ItemData> dataSource; public CustomListAdapter(List<ItemData> dataSource) { this.dataSource = dataSource; // 开启稳定ID支持 setHasStableIds(true); } // 返回自定义业务ID @Override public long getItemId(int position) { // 这里返回你业务侧预先定义好的条目唯一ID即可,比如数据表里的主键ID return dataSource.get(position).getCustomItemId(); } @NonNull @Override public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { // 正常实现ViewHolder创建逻辑即可 View itemView = LayoutInflater.from(parent.getContext()) .inflate(R.layout.layout_list_item, parent, false); return new ItemViewHolder(itemView); } @Override public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { // 正常实现条目绑定逻辑即可 ItemData currentData = dataSource.get(position); holder.titleText.setText(currentData.getTitle()); } @Override public int getItemCount() { return dataSource.size(); } static class ItemViewHolder extends RecyclerView.ViewHolder { TextView titleText; public ItemViewHolder(@NonNull View itemView) { super(itemView); titleText = itemView.findViewById(R.id.tv_title); } } }
配置完成后,RecyclerView就会使用你指定的自定义ID替换自动生成的ID,完全适配无障碍识别、条目状态持久化、精准动画等依赖条目ID的业务场景。
内容的提问来源于stack exchange,提问作者Michael
相关产品推荐
相关产品推荐

