🚀 RecyclerView 进阶优化指南 相比之前的版本,这次的改进包括:
✅ 使用 DiffUtil 优化数据更新 (避免 notifyDataSetChanged()) 
✅ 使用 ViewBinding 简化 ViewHolder 代码  
✅ 封装 Adapter 支持 MutableList(支持增删改查)  
✅ 优化 onClick 事件,让 RecyclerView 更易扩展  
✅ 支持 Grid/瀑布流/线性布局  
 
 
1️⃣ 添加 RecyclerView 依赖 确保你的 build.gradle 添加了:
1 2 3 4 dependencies {     implementation 'androidx.recyclerview:recyclerview:1.3.2'     implementation 'androidx.viewbinding:viewbinding:7.3.1' // 使用 ViewBinding } 
 
 
2️⃣ 在 activity_main.xml 中添加 RecyclerView 1 2 3 4 5 <androidx.recyclerview.widget.RecyclerView     android:id="@+id/recyclerView"     android:layout_width="match_parent"     android:layout_height="match_parent"     android:padding="10dp"/> 
 
 
3️⃣ 创建数据模型 1 2 3 4 5 6 data class Diary(     val id: Int,         // 方便更新和删除     val title: String,       val content: String,      val date: String ) 
 
 
4️⃣ 使用 DiffUtil 优化 Adapter 🚀 DiffUtil 可以高效更新 RecyclerView,避免全量刷新,提高性能。
创建 DiaryDiffCallback 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 class DiaryDiffCallback(     private val oldList: List<Diary>,     private val newList: List<Diary> ) : DiffUtil.Callback() {          override fun getOldListSize(): Int = oldList.size     override fun getNewListSize(): Int = newList.size     // 判断是否是同一项(通常比较 ID)     override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {         return oldList[oldItemPosition].id == newList[newItemPosition].id     }     // 判断内容是否相同(避免不必要的刷新)     override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {         return oldList[oldItemPosition] == newList[newItemPosition]     } } 
 
 
5️⃣ 优化 Adapter(使用 ViewBinding) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 class DiaryAdapter(     private var diaryList: MutableList<Diary>, // 让数据可变     private val onItemClick: (Diary) -> Unit ) : RecyclerView.Adapter<DiaryAdapter.DiaryViewHolder>() {     // 使用 ViewBinding 简化 ViewHolder     class DiaryViewHolder(val binding: ItemDiaryBinding) : RecyclerView.ViewHolder(binding.root)     override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): DiaryViewHolder {         val binding = ItemDiaryBinding.inflate(LayoutInflater.from(parent.context), parent, false)         return DiaryViewHolder(binding)     }     override fun onBindViewHolder(holder: DiaryViewHolder, position: Int) {         val diary = diaryList[position]         with(holder.binding) {             tvTitle.text = diary.title             tvContent.text = diary.content             tvDate.text = diary.date             root.setOnClickListener { onItemClick(diary) } // 处理点击事件         }     }     override fun getItemCount(): Int = diaryList.size     // 🚀 使用 DiffUtil 刷新数据,避免全量刷新     fun updateData(newList: List<Diary>) {         val diffResult = DiffUtil.calculateDiff(DiaryDiffCallback(diaryList, newList))         diaryList.clear()         diaryList.addAll(newList)         diffResult.dispatchUpdatesTo(this)     }     // 增删改查方法     fun addDiary(diary: Diary) {         diaryList.add(0, diary)  // 插入到第一个位置         notifyItemInserted(0)     }     fun removeDiary(position: Int) {         if (position in diaryList.indices) {             diaryList.removeAt(position)             notifyItemRemoved(position)         }     } } 
 
 
6️⃣ 创建 item_diary.xml 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"     android:layout_width="match_parent"     android:layout_height="wrap_content"     android:orientation="vertical"     android:padding="10dp"     android:background="@android:color/white">     <TextView         android:id="@+id/tvTitle"         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:textSize="18sp"         android:textColor="@android:color/black"         android:textStyle="bold"/>     <TextView         android:id="@+id/tvContent"         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:textSize="16sp"         android:textColor="@android:color/darker_gray"         android:maxLines="2"         android:ellipsize="end"/>     <TextView         android:id="@+id/tvDate"         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:textSize="14sp"         android:textColor="@android:color/holo_blue_dark"/> </LinearLayout> 
 
 
7️⃣ 在 MainActivity 绑定 RecyclerView 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 class MainActivity : AppCompatActivity() {          private lateinit var recyclerView: RecyclerView     private lateinit var diaryAdapter: DiaryAdapter     override fun onCreate(savedInstanceState: Bundle?) {         super.onCreate(savedInstanceState)         setContentView(R.layout.activity_main)         recyclerView = findViewById(R.id.recyclerView)         recyclerView.layoutManager = LinearLayoutManager(this)         // 初始数据         val diaryList = mutableListOf(             Diary(1, "今日心情", "今天天气很好,心情愉快!", "2025-03-17"),             Diary(2, "学习 Kotlin", "RecyclerView 真的很好用!", "2025-03-16")         )         // 绑定 Adapter         diaryAdapter = DiaryAdapter(diaryList) { diary ->             Toast.makeText(this, "点击了: ${diary.title}", Toast.LENGTH_SHORT).show()         }         recyclerView.adapter = diaryAdapter         // 模拟 3 秒后刷新数据         Handler(Looper.getMainLooper()).postDelayed({             val newData = diaryList + Diary(3, "记账", "今天吃了火锅,花了 120 元", "2025-03-15")             diaryAdapter.updateData(newData)         }, 3000)     } } 
 
 
8️⃣ 可选优化 (1)网格布局 1 recyclerView.layoutManager = GridLayoutManager(this, 2) // 2 列 
 
(2)瀑布流布局 1 recyclerView.layoutManager = StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL) 
 
 
四种通知方法 1. notifyDataSetChanged()(全部更新一遍) 1 adapter.notifyDataSetChanged() 
 
范围 :整个数据集 
性能 :较低,重绘所有项目 
使用 :数据大量变化或不确定具体变化时 
 
2. notifyItemChanged()(精确更新) 1 adapter.notifyItemChanged(position) 
 
范围 :单个项目 
性能 :高,只更新指定项目 
使用 :明确知道哪个项目变化时 
 
3. notifyItemInserted()(插入通知) 1 adapter.notifyItemInserted(position) 
 
范围 :新插入的项目 
性能 :高,只处理新项目 
使用 :添加新项目时 
 
4. notifyItemRemoved()(删除通知) 1 adapter.notifyItemRemoved(position) 
 
范围 :被删除的项目 
性能 :高,只处理删除 
使用 :删除项目时 
 
🎯 总结 
改进点 
说明 
 
 
✅ 使用 DiffUtil  
优化数据更新 ,避免 notifyDataSetChanged() 
 
✅ 使用 ViewBinding  
减少 findViewById 代码 ,提高可读性 
 
✅ 封装增删改查方法  
addDiary() 和 removeDiary() 
 
✅ 支持 MutableList  
让数据可变 ,更方便操作 
 
✅ 支持 Grid/瀑布流布局  
适配不同 UI 需求