likes
comments
collection
share

Android-我对适配器模式的理解

作者站长头像
站长
· 阅读数 15

适配器模式的思想

适配器模式的思想是将一个类的接口(抽象类)转换成客户端所期望的另一个接口(抽象类),从而使原本不兼容的类能够一起工作,感觉有点抽象吧。

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()
}

总结

我前面忘说了,适配器模式分为两种:类适配器(基于继承)和对象适配器(基于组合),以上代码都是基于对象适配器。不过不重要,区别不是很大,代码也都容易理解。

适配器模式是一种通过适配器类来转换类或对象的接口,使原本不兼容的类能够协同工作的设计模式。它提供了一种解耦的方式,能够在不修改现有代码的情况下实现接口的适配,并为系统的灵活性和扩展性提供支持。