适配器形式的思维

适配器形式的思维是将一个类的接口抽象类)转化成客户端所期望的另一个接口(抽象类),从而使原本不兼容的类可以一同工作,感觉有点抽象吧。

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的接口进行适配,完成了以下功用:

  1. 创立视图项:适配器担任依据RecyclerView的要求,创立视图项的布局,并将其封装在ViewHolder中返回。适配器经过重写onCreateViewHolder()办法来完成这一功用。

缓存复用机制的文章可以微信搜索“星际码仔”,里面写的非常清晰易懂。

  1. 绑定数据项:适配器担任依据RecyclerView的要求,将数据集合中的每个数据项绑定到对应的视图项上。适配器经过重写onBindViewHolder()办法来完成这一功用。
  2. 办理数据集合:适配器担任办理数据集合的增删改查等操作。当数据集合发生变化时,适配器会担任通知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()
}

总结

我前面忘说了,适配器形式分为两种:类适配器(根据继承)和目标适配器(根据组合),以上代码都是根据目标适配器。不过不重要,区别不是很大,代码也都容易了解。

适配器形式是一种经过适配器类来转化类或目标的接口,使原本不兼容的类可以协同工作的设计形式。它供给了一种解耦的办法,可以在不修正现有代码的情况下完成接口的适配,并为体系的灵活性和扩展性供给支持。