关注个人主页,技术不迷路~
适配器模式的思想
适配器模式的思想是将一个类的接口(抽象类)转换成客户端所期望的另一个接口(抽象类),从而使原本不兼容的类能够一起工作,感觉有点抽象吧。
RecycleView中的Adapter
拿我们最常用的的RecycleView对应的Adapter举例:
data class Item(
val title: String = ""
)
class ItemAdapter(private val itemList: List<Item>) :
RecyclerView.Adapter<ItemAdapter.ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
// 创建视图项的布局
val itemView =
LayoutInflater.from(parent.context).inflate(R.layout.item_layout, parent, false)
return ViewHolder(itemView)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
// 将数据项绑定到视图上
val item = itemList[position]
holder.titleTextView.text = item.title
}
override fun getItemCount(): Int {
return itemList.size
}
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
var titleTextView: TextView
init {
titleTextView = itemView.findViewById(R.id.titleTextView)
}
}
}
使用方式
rv = findViewById(R.id.rv)
val itemList = listOf(Item("item1"), Item("item2"), Item("item3"))
adapter = ItemAdapter(itemList)
rv.adapter = adapter
我们的目的是需要将一组数据,展示到界面上,而这里适配器的作用就是将数据集合与RecyclerView的接口进行适配,实现了以下功能:
- 创建视图项:适配器负责根据RecyclerView的要求,创建视图项的布局,并将其封装在ViewHolder中返回。适配器通过重写onCreateViewHolder()方法来实现这一功能。
缓存复用机制的文章可以微信搜索“星际码仔”,里面写的非常清晰易懂。
- 绑定数据项:适配器负责根据RecyclerView的要求,将数据集合中的每个数据项绑定到对应的视图项上。适配器通过重写onBindViewHolder()方法来实现这一功能。
- 管理数据集合:适配器负责管理数据集合的增删改查等操作。当数据集合发生变化时,适配器会负责通知RecyclerView进行相应的刷新。适配器提供了方法来操作数据集合,例如添加、移除、更新数据项等。
而我们的数据集合不就是通过List接口创建出来的吗,然后通过适配器的构造方法传入。
我们写的Adapter实现的是另一组接口(抽象类)
class ItemAdapter(private val itemList: List<Item>) :
RecyclerView.Adapter<ItemAdapter.ViewHolder>() {
省略。。。
}
RecycleView.java
public abstract static class Adapter<VH extends ViewHolder> {
省略。。。
}
可以看到RecycleView中的Adapter是一个抽象类,就是客户端所期待的另一组接口,这样就建立了联系。通过适配器模式,RecyclerView可以动态地创建和绑定视图项,实现数据的展示和滚动效果。适配器提供了一种灵活、可扩展的机制,使得可以根据需要定制适配器类来满足特定的数据展示和交互需求。
通过适配器模式,RecyclerView能够将数据项和视图项的处理逻辑分离开来,提供了一种可重用和灵活的机制来管理和展示大量的数据。适配器负责处理数据和视图之间的关系。
练练手
//原始接口
interface IPrimaryData {
fun getDataList(): List<String>
}
//原始接口的实现类
class PrimaryData(private val dataList: List<String>) : IPrimaryData {
override fun getDataList(): List<String> {
return dataList
}
}
//目标接口
abstract class UITarget {
abstract fun onCreateViewHolder()
abstract fun onBindViewHolder(holder: ViewHolder, position: Int)
}
//适配器
class DataAdapter(private val dataList: List<String>) : UITarget() {
override fun onCreateViewHolder() {
/** 创建视图
* 伪代码
val itemView = LayoutInflater.from(parent.context).inflate(R.layout.item_layout, parent,
false)
return ViewHolder(itemView)
*
*/
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
//伪代码
val item = dataList[position]
//holder.titleTextView.text = item.title
}
}
//使用方式
//以下三行为脱裤子放屁,就是将数据传入到PrimaryData类中的getDataList方法中,不加任何修改的原路返回
val dataList = listOf("item 1", "item 2", "item 3")
val primaryData: IPrimaryData = PrimaryData(dataList)
val dataList1 = primaryData.getDataList()
//将接口数据传入适配器中,进行适配
val adapter: UITarget = DataAdapter(dataList1)
以上代码不能运行,看个意思就行,不知道同学是否理解了适配器模式?
其他运用场景
假设正在接广告SDK,广告SDK提供的回调方法过多,但是用不着那么多,写起来老长的,影响美观,可以考虑用适配器模式来优化下
// 广告SDK原有的接口,有5个回调方法
interface AdSDKCallback {
fun onAdLoaded()
fun onAdFailedToLoad()
fun onAdShown()
fun onAdClicked()
fun onAdClosed()
}
// 新的接口,只包含需要的方法
interface NewCallback {
fun onAdLoaded()
fun onAdClicked()
}
// 适配器类,实现新的接口并持有广告SDK接口的实例
class AdSDKAdapter(private val adSDKCallback: AdSDKCallback) : NewCallback {
override fun onAdLoaded() {
adSDKCallback.onAdLoaded()
// 其他逻辑处理
}
override fun onAdClicked() {
adSDKCallback.onAdClicked()
// 其他逻辑处理
}
}
fun main() {
val adSDKCallback: AdSDKCallback = AdSDKImplementation()
val adapter: NewCallback = AdSDKAdapter(adSDKCallback)
// 使用新的接口的方法
adapter.onAdLoaded()
adapter.onAdClicked()
}
总结
我前面忘说了,适配器模式分为两种:类适配器(基于继承)和对象适配器(基于组合),以上代码都是基于对象适配器。不过不重要,区别不是很大,代码也都容易理解。
适配器模式是一种通过适配器类来转换类或对象的接口,使原本不兼容的类能够协同工作的设计模式。它提供了一种解耦的方式,能够在不修改现有代码的情况下实现接口的适配,并为系统的灵活性和扩展性提供支持。
网友评论