【Android学习】Adapter中使用Context

参考文章

文章目录

  • [1. 通过 Adapter 构造函数传入 Context](#1. 通过 Adapter 构造函数传入 Context)
  • [2. 通过 Parent.context 获取](#2. 通过 Parent.context 获取)
  • [3. 通过 onAttachedToRecyclerView() 方法获取](#3. 通过 onAttachedToRecyclerView() 方法获取)
  • [4. 通过 ImageView 获取 context (局限于本例子中)](#4. 通过 ImageView 获取 context (局限于本例子中))
  • [5. 四种方法对比分析](#5. 四种方法对比分析)
  • [6. 作者推荐的方法](#6. 作者推荐的方法)

需求: Glide加载图片需要用到Context


1. 通过 Adapter 构造函数传入 Context

kotlin 复制代码
class MyAdapter(
    private val context: Context,
    private val dataList: List<MyData>
) : RecyclerView.Adapter<MyAdapter.MyViewHolder>() {
​
    class MyViewHolder(val binding: RcyItemViewBinding) :
        RecyclerView.ViewHolder(binding.root) {
    }
​
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
        val binding = RcyItemViewBinding.inflate(
            LayoutInflater.from(parent.context),
            parent,
            false
        )
        return MyViewHolder(binding)
    }
​
    override fun getItemCount(): Int = dataList.size
​
    override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
        val data = dataList[position]
        holder.binding.apply {
            Glide.with(context).load(data.imageUrl).into(holder.binding.imageIv)
            holder.binding.contentTv.text = data.content
        }
    }
}

2. 通过 Parent.context 获取

kotlin 复制代码
class MyAdapter(private val dataList: List<MyData>) :
    RecyclerView.Adapter<MyAdapter.MyViewHolder>() {
​
    private lateinit var mContext: Context  //
​
    class MyViewHolder(val binding: RcyItemViewBinding) :
        RecyclerView.ViewHolder(binding.root) {
​
    }
​
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
        mContext = parent.context //
        val binding = RcyItemViewBinding.inflate(
            LayoutInflater.from(parent.context),
            parent,
            false
        )
        return MyViewHolder(binding)
    }
​
    override fun getItemCount(): Int = dataList.size
​
    override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
        val data = dataList[position]
        holder.binding.apply {
            Glide.with(mContext).load(data.imageUrl).into(holder.binding.imageIv)
            holder.binding.contentTv.text = data.content
        }
    }
}
​

3. 通过 onAttachedToRecyclerView() 方法获取

onAttachedToRecyclerView() 是 RecyclerView.Adapter 类中的一个回调方法,主要用于在 RecyclerView 适配器与 RecyclerView 关联时执行一些初始化操作。这个方法在适配器绑定到 RecyclerView 时被调用,通常用来执行需要依赖于 RecyclerView 的上下文的初始化逻辑,例如设置布局管理器、添加 ItemAnimator 或进行数据初始化等。

kotlin 复制代码
class MyAdapter(private val dataList: List<MyData>) :
    RecyclerView.Adapter<MyAdapter.MyViewHolder>() {
​
    private lateinit var mContext: Context//
​
    override fun onAttachedToRecyclerView(recyclerView: RecyclerView) {
        super.onAttachedToRecyclerView(recyclerView)
        mContext = recyclerView.context//
    }
​
    class MyViewHolder(val binding: RcyItemViewBinding) :
        RecyclerView.ViewHolder(binding.root) {
​
    }
​
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
        val binding = RcyItemViewBinding.inflate(
            LayoutInflater.from(parent.context),
            parent,
            false
        )
        return MyViewHolder(binding)
    }
​
    override fun getItemCount(): Int = dataList.size
​
    override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
        val data = dataList[position]
        holder.binding.apply {
            Glide.with(mContext).load(data.imageUrl).into(holder.binding.imageIv)
            holder.binding.contentTv.text = data.content
        }
    }
}

4. 通过 ImageView 获取 context (局限于本例子中)

kotlin 复制代码
class MyAdapter(private val dataList: List<MyData>) :
    RecyclerView.Adapter<MyAdapter.MyViewHolder>() {
​
    class MyViewHolder(val binding: RcyItemViewBinding) :
        RecyclerView.ViewHolder(binding.root) {
​
    }
​
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
        val binding = RcyItemViewBinding.inflate(
            LayoutInflater.from(parent.context),
            parent,
            false
        )
        return MyViewHolder(binding)
    }
​
    override fun getItemCount(): Int = dataList.size
​
    override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
        val data = dataList[position]
        holder.binding.apply {
            Glide.with(imageIv.context).load(data.imageUrl).into(holder.binding.imageIv)
            holder.binding.contentTv.text = data.content
        }
    }
}

5. 四种方法对比分析

  • 这四种方法虽然看着写法很不一样,但是其获取到的 context 其实都是同一个,那就是 MainActivity。
  • 方法1:既然可以在类内部直接获取到的参数,完全就没有必要再写一个参数从外部导入
  • 方法2:不会导致内存泄漏,但是我也不推荐这样的写法,毕竟 onCreateViewHolder() 方法的执行次数是由 itemCount
    所决定的,所以也就意味着 mContext = parent.context 也会执行 itemCount次,明明一次就行,其它多余的操作,会造成不必要的开销
  • 方法3:通过 onAttachedToRecyclerView() 方法,只会进行一次赋值操作,很OK啊,但毕竟他又是定义全局变量,又是覆写方法

6. 作者推荐的方法

kotlin 复制代码
class MyAdapter(private val dataList: List<MyData>) :
    RecyclerView.Adapter<MyAdapter.MyViewHolder>() {
​
    class MyViewHolder(
        private val context: Context,
        private val binding: RcyItemViewBinding
    ) :
        RecyclerView.ViewHolder(binding.root) {
​
        fun bind(data: MyData) {
            Glide.with(context).load(data.imageUrl).into(binding.imageIv)
            binding.contentTv.text = data.content
        }
    }
​
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
        val binding = RcyItemViewBinding.inflate(
            LayoutInflater.from(parent.context),
            parent,
            false
        )
        return MyViewHolder(parent.context, binding)
    }
​
    override fun getItemCount(): Int = dataList.size
​
    override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
        holder.bind(dataList[position])
    }
}

我选择在 onCreateViewHolder() 通过 parent.context 方法获取 context,但是,不是赋值给全部变量 mContext,而是直接传给 ViewHolder作为一个私有变量供其使用。

相关推荐
~kiss~7 小时前
A Survey of On-Policy Distillation for LLMs 学习(一)
学习
LinXunFeng8 小时前
拿竞品 App 一扫,技术栈全暴露了
android·flutter·开源
小杨小杨、努力变强!8 小时前
python学习笔记
笔记·学习
Gracker11 小时前
AIW:从系统机制到性能排查,一本可以对照源码的 Android 电子书
android
三少爷的鞋11 小时前
代码越来越便宜,判断力越来越贵:AI 时代的 Android 架构与协程避坑指南
android
Gracker12 小时前
SmartPerfetto 1.19.0:换过分析引擎之后,这次更新了什么
android
Star(up up up)14 小时前
Redis Windows 安装教程:使用Windows 的 Redis 压缩包
redis·笔记·学习·程序人生·云原生·学习方法·改行学it
乌暮16 小时前
Spring AOP 与 Spring 事务:用大白话彻底理解原理与实践
java·数据库·spring boot·后端·sql·学习·spring
HQL_seven16 小时前
【Android】BroadcastReceiver 详解
android
_祝你今天愉快18 小时前
Paint Cavans高级绘制:[二] Paint-滤镜,XFERMODE
android