适配器形式的思维
适配器形式的思维是将一个类的接口(抽象类)转化成客户端所期望的另一个接口(抽象类),从而使原本不兼容的类可以一同工作,感觉有点抽象吧。
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()
}
总结
我前面忘说了,适配器形式分为两种:类适配器(根据继承)和目标适配器(根据组合),以上代码都是根据目标适配器。不过不重要,区别不是很大,代码也都容易了解。
适配器形式是一种经过适配器类来转化类或目标的接口,使原本不兼容的类可以协同工作的设计形式。它供给了一种解耦的办法,可以在不修正现有代码的情况下完成接口的适配,并为体系的灵活性和扩展性供给支持。