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

相关推荐
光影少年42 分钟前
AIGG人工智能生态及学习路线和应用领域
人工智能·学习
递归不收敛44 分钟前
多模态学习大纲笔记(未完成)
人工智能·笔记·学习·自然语言处理
AI智能架构工坊1 小时前
提升AI虚拟健康系统开发效率:架构师推荐10款低代码开发平台
android·人工智能·低代码·ai
百锦再1 小时前
低代码开发的约束性及ABP框架的实践解析
android·开发语言·python·低代码·django·virtualenv·rxjava
那我掉的头发算什么1 小时前
【数据库】navicat的下载以及数据库约束
android·数据库·数据仓库·sql·mysql·数据库开发·数据库架构
FPGA-李宇航2 小时前
FPGA中,“按键控制LED灯实验”学习中常见问题、解决思路和措施以及经验总结!!!(新手必看)
学习·fpga开发·按键控制led灯
明道源码2 小时前
Android Studio 应用运行到真机设备
android·ide·android studio
生莫甲鲁浪戴2 小时前
Android Studio新手开发第二十五天
android·ide·android studio
Varpb2 小时前
android studio-设置android模拟器屏幕自动旋转
android·android studio
正经教主3 小时前
【Trae+AI】和Trae学习搭建App_01:项目架构设计与环境搭建
学习·app