目录
介绍
定义
使用场景
代码实现
适配器模式在我们的开发中使用概率很高,从代码中随处可见的Adapter就可以判断出来,最早的ListView、GridView到现在最新的RecycleView都需要使用Adapter,并且在开发中遇到优化问题、出错概率较大的也基本出自Adapter,真是一个让人又爱又恨的角色。Adapter的目的就是将两个不兼容的类融合到一起,将不同的东西通过一种转换使得它们能够协作起来,例如,经常碰到要在两个没有关系的类型之间进行交互,第一个解决方案是修改各自类的接口,但是如果没有源代码或者任何一方不愿意为了一个应用而修改接口,此时我们就需要使用一个Adapter,在这两种接口之间创建一个粘合剂,这个Adapter会将这两个接口进行兼容,在不修改原有代码的情况下满足需求。
适配器模式把一个类的接口变换成客户端所期待的另一种接口,从而使原本因为接口不匹配而无法在一起工作的两个类能够在一起工作。
1、系统需要使用现有的类,而此类的接口不符合系统的需要,即接口不兼容;
2、想要建立一个可以重复使用的类,用于与一些彼此之间没有太大关联的一些类,包括一些可能在将来引进的类一起工作;
3、需要一个统一的输出接口,而输入端类型不可预知;
我们以充电器为例,用伪代码来模拟一下,家用电都是220V,而我们手机的充电电压为5V,需要经过充电器的适配,家用电Volt220源码如下:
public class Volt220 {
public int getVolt220() {
return 220;
}
}
需要的目标输入接口FiveVolt,源码如下:
public interface FiveVolt {
public int getVolt5();
}
这个接口定义了输入行为,也就是说,不管你是220V还是380V,只要实现了该接口,都可以给我们的手机充电,现在输入不可预知,而输出行为固定,就需要经过充电器来进行适配了。适配器VoltAdapter的源码如下:
public class VoltAdapter implements FiveVolt {
private Volt220 mVolt220;
public VoltAdapter(Volt220 volt220) {
mVolt220 = volt220;
}
public int getVolt220() {
return mVolt220.getVolt220();
}
@Override
public int getVolt5() {
return transform(getVolt220());
}
private int transform(int input) {
return 5;
}
}
适配器也是实现了FiveVolt接口,transform方法中会把各种不同的输入转换成统一的输出,这就是适配器模式。
我们随便看一下RecyclerView.Adapter的简单示例,代码如下:
package com.hong.camera;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.recyclerview.widget.RecyclerView;
public class ViewAdapter extends RecyclerView.Adapter {
private String[] mNames;
public ViewAdapter(String[] names) {
this.mNames = names;
}
@Override
public ViewAdapter.Holder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = View.inflate(parent.getContext(), R.layout.item, null);
Holder holder = new Holder(view);
return holder;
}
@Override
public void onBindViewHolder(Holder holder, int position) {
holder.text.setText(mNames[position]);
holder.itemView.setTag(position);
}
@Override
public int getItemCount() {
return mNames.length;
}
public class Holder extends RecyclerView.ViewHolder {
private final TextView text;
public Holder(View itemView) {
super(itemView);
text = itemView.findViewById(R.id.text_item);
}
}
}
输入数据无法预知,当然也不需要关心,而输出数据是固定的,就是要添加到RecycleView上的子View,而这些子View就是通过Adapter定义的onCreateViewHolder、onBindViewHolder两个方法生成的,任何的View布局RecycleView也不关心,都是输入方自己实现,我只关心onCreateViewHolder方法中你把itemView绘制出来组装到holder上返回给我,onBindViewHolder方法中根据你自己的定义的View把该填充的view数据给我填充上就行了。
从思想上的认识,让我自己都感觉到佩服,之前只是简单的写代码,但是没有从这样的高度认识到适配器模型的设计思想,是不是挺厉害,任何无法预知的输入都可以适配,就通过我最终关心的几个接口定义好适配行为就可以了。