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

相关推荐
黄林晴21 小时前
如何判断手机是否是纯血鸿蒙系统
android
火柴就是我21 小时前
flutter 之真手势冲突处理
android·flutter
法的空间21 小时前
Flutter JsonToDart 支持 JsonSchema
android·flutter·ios
循环不息优化不止21 小时前
深入解析安卓 Handle 机制
android
恋猫de小郭1 天前
Android 将强制应用使用主题图标,你怎么看?
android·前端·flutter
jctech1 天前
这才是2025年的插件化!ComboLite 2.0:为Compose开发者带来极致“爽”感
android·开源
用户2018792831671 天前
为何Handler的postDelayed不适合精准定时任务?
android
叽哥1 天前
Kotlin学习第 8 课:Kotlin 进阶特性:简化代码与提升效率
android·java·kotlin
Cui晨1 天前
Android RecyclerView展示List<View> Adapter的数据源使用View
android
氦客1 天前
Android Doze低电耗休眠模式 与 WorkManager
android·suspend·休眠模式·workmanager·doze·低功耗模式·state_doze