【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作为一个私有变量供其使用。

相关推荐
wdfk_prog11 分钟前
[Linux]学习笔记系列 --[drivers][base]map
linux·笔记·学习
浅念-13 分钟前
链表经典面试题目
c语言·数据结构·经验分享·笔记·学习·算法
2501_9444241231 分钟前
Flutter for OpenHarmony游戏集合App实战之俄罗斯方块七种形状
android·开发语言·flutter·游戏·harmonyos
石像鬼₧魂石38 分钟前
Windows Server 2003 域控制器靶机搭建与渗透环境配置手册
linux·windows·学习
啥都会点的大秀1 小时前
声学仿真学习笔记
笔记·学习
好奇龙猫1 小时前
【AI学习-comfyUI学习-三十六节-黑森林-融合+扩图工作流-各个部分学习】
人工智能·学习
:mnong2 小时前
通过手写识别数字可视化学习卷积神经网络原理
人工智能·学习·cnn
不会Android的潘潘2 小时前
受限系统环境下的 WebView 能力演进:车载平台 Web 渲染异常的根因分析与优化实践
android·java·前端·aosp
建军啊2 小时前
java web常见lou洞
android·java·前端
豆奶dudu2 小时前
安卓应用签名生成+微信开放平台安卓应用签名
android·微信开放平台