RecyclerView.Adapter → ListAdapter

RecyclerView.Adapter → ListAdapter

老写法(Java)

java 复制代码
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {

    private List<Item> items = new ArrayList<>();

    public void setData(List<Item> newItems) {
        items.clear();
        items.addAll(newItems);
        notifyDataSetChanged();
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.item_row, parent, false);
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
        Item item = items.get(position);
        holder.tvName.setText(item.getName());
    }

    @Override
    public int getItemCount() {
        return items.size();
    }

    static class ViewHolder extends RecyclerView.ViewHolder {
        TextView tvName;
        ViewHolder(View itemView) {
            super(itemView);
            tvName = itemView.findViewById(R.id.tv_name);
        }
    }
}

问题在哪里

notifyDataSetChanged() 会刷新整个列表,没有动画,滚动位置也可能跳动。数据量一大明显卡顿,用户体验差。

新写法(Kotlin + ListAdapter)

kotlin 复制代码
class MyAdapter : ListAdapter<Item, MyAdapter.ViewHolder>(DiffCallback) {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val view = LayoutInflater.from(parent.context)
                .inflate(R.layout.item_row, parent, false)
        return ViewHolder(view)
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        holder.tvName.text = getItem(position).name
    }

    class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        val tvName: TextView = itemView.findViewById(R.id.tv_name)
    }

    companion object {
        private val DiffCallback = object : DiffUtil.ItemCallback<Item>() {
            override fun areItemsTheSame(oldItem: Item, newItem: Item) =
                oldItem.id == newItem.id

            override fun areContentsTheSame(oldItem: Item, newItem: Item) =
                oldItem == newItem
        }
    }
}

data class Item(val id: Long, val name: String)

数据更新时只需:

kotlin 复制代码
adapter.submitList(newList)

一句话注意

submitList() 内部在后台线程做 diff 计算,不会卡主线程。但注意不要在高频更新的场景(比如每秒数十次)下反复 new 一个新 list 往里传,容易造成资源浪费。

如果只是列表里某一项的某个字段变了,需要重写 areContentsTheSame,否则 notifyDataSetChanged() 依然需要手动调用。areItemsTheSame 是判断"是不是同一条",通常比 ID;areContentsTheSame 是判断"内容是否变了",通常 equals()


Java Android 老项目迁移系列,持续更新中。

相关推荐
long31629 分钟前
封装(Encapsulation)
java·人工智能·ai·ai编程
yaoxin52112331 分钟前
502. Java 反射 - 编写 MessageInterceptor 类
java·开发语言
风流 少年35 分钟前
Spring AI 2.0:阿里云百炼平台(工作流应用)
java·后端·spring
长谷深风11141 分钟前
AI Tool 设计:粒度、参数与错误恢复怎么做
java·大数据·人工智能·ai agent·agent工作流·智能体设计·ai产品设计
QQ_21696290962 小时前
【项目编号:project95315】SpringBoot公共自习室管理系统:座位预约、房间管理、签到核销、公告规则完整实战
java·spring boot·后端
alexhilton2 小时前
规范驱动开发:让AI生成符合预期的KMP代码
android·kotlin·android jetpack
嵌入式阿蔡2 小时前
面试高频考点 01:volatile / 中断 / 堆栈 八股精讲
java·面试·职场和发展·嵌入式实时数据库
秋饼2 小时前
LangChain4j + Java 实现企业级 Text-to-SQL 智能问数系统:从自然语言到安全可控的数据洞察
java·ai·技术分享·后端开发
Escalating_xu3 小时前
【C++ STL简介】从六大组件到容器、迭代器与算法协作
java·c++·算法
何以解忧,唯有..3 小时前
Python os模块详解:文件与目录操作指南
java·服务器·python