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 老项目迁移系列,持续更新中。

相关推荐
Wang's Blog5 小时前
Java框架 SpringCloud 快速入门: 从服务拆分到注册中心的落地路线
java·开发语言·spring cloud
传奇开心果编程5 小时前
【Compose Multiplatform 跨端开发学与练】第2课 Compose 基础语法
android·windows·学习·ui·ios·kotlin·composer
Wang's Blog6 小时前
Java框架 SpringCloud 快速入门: 全局过滤器(GlobalFilter)自定义鉴权
java·开发语言·spring cloud
paopaokaka_luck6 小时前
高校社团管理(AI辅助任务分配、协同过滤算法推荐、ECharts数据可视化、活动参与闭环、校园交流与反馈、器材借还管理)
java·前端·javascript·spring boot·数据分析·echarts
vx_Biye_Design6 小时前
springboot小区管理系统68491-计算机课程设计、毕业设计
java·vue.js·spring boot·后端·spring·课程设计·express
专业程序开发源6 小时前
springboot外卖系统94294-计算机课程设计、毕业设计
java·vue.js·spring boot·后端·spring·php·课程设计
Moshow郑锴8 小时前
sql-pipeline - 基于PostgreSQL的SQL健康检查与发布编排平台
java·sql
Wang's Blog15 小时前
Java 项目实战: 外卖平台优化-Nginx配置文件结构与块层级
java·开发语言·nginx
\光辉岁月/17 小时前
5.java-数组
java·开发语言
谢亮_vipxieliang17 小时前
Spring 事务失效的常见场景
java·开发语言·数据库·spring boot