文章目录
- [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作为一个私有变量供其使用。