Android适配器模式,手写ListView体验适配器

编程入门 行业动态 更新时间:2024-10-10 16:17:40

Android<a href=https://www.elefans.com/category/jswz/34/1770284.html style=适配器模式,手写ListView体验适配器"/>

Android适配器模式,手写ListView体验适配器

文章目录

    • 适配器模式
      • 一. 生活小场景
      • 二. 适配器模式定义
      • 三. 代码小案例
      • 四. RecyclerView的适配器模式
      • 五. 手写ListView体验适配器模式

适配器模式

一. 生活小场景

​ 生活中我们将风能转换成我们的电能,如果说我们直接拿到风能,能够把我们的电灯发亮吗?是不行的,对不对,所以这是两个不能够兼容的东西,风能是不能够直接把我们的电灯泡点亮的,那怎么办?只能通过发电机将我们的风能转换成我们的电能,再通过电能去点亮电灯,所以我们的发电机就相当于适配器,它把两个不能兼容的接口,让他们兼容在了一起,宏观上来说也是风能点亮了我们的灯泡。

二. 适配器模式定义

​ 适配器模式 (Adapter Pattern) 是作为两个不兼容的接口之间的桥梁。这种类型的设计模式属于结构型模式,它结合了两个独立接口的功能。这种模式涉及到一个单一的类,该类负责加入独立的或不兼容的接口功能。

三. 代码小案例

我们这里举例一个电脑通过usb链接显示器的hdmi的例子。

/*** 目标*/
public interface Target {void method();
}
/*** 具体目标是需要一个HDMI的接口*/
public class ConcreteTarget implements Target{@Overridepublic void method() {Log.w("simple ConcreteTarget", "我需要使用HDMI接口");}
}
/*** 源数据,电脑和屏幕连接*/
public class Adaptee {public void method2() {Log.w("simple Adatee", "我需要使用USB接口");}
}
/*** 桥梁连接,继承自源数据Adaptee,并且实现目标数据的接口,意思是两边都不落下,作为桥梁*/
public class Adapter extends Adaptee implements Target{@Overridepublic void method() {//拿到源数据super.method2();//这句日志可以理解为转接头,源数据--->目标数据Log.w("simple Adapter", "使用了USB转HDMI线,现在可以使用在HDMI线上了");}
}

上面书写的这个适配器模式,可以理解为类层面的适配器模式,类适配器,灵活性不是很高。

我们修改下

/*** 桥梁连接,继承自源数据Adaptee,并且实现目标数据的接口,意思是两边都不落下,作为桥梁*/
public class Adapter extends Adaptee implements Target {private Adaptee adaptee;public Adapter(Adaptee adaptee) {this.adaptee = adaptee;}@Overridepublic void method() {//拿到源数据adaptee.method2();//这句日志可以理解为转接头,源数据--->目标数据Log.w("simple Adapter", "使用了USB转HDMI线,现在可以使用在HDMI线上了");}
}

测试代码:

public class TestActivity extends AppCompatActivity {@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Adaptee adaptee = new Adaptee();Adapter adapter = new Adapter(adaptee);adapter.method();}
}

从结果看出运行成功,意味着适配器桥接usb和hdmi两个接口成功了。

小结:

  1. 两个不兼容的内容进行了桥接整合,通过中介者Adapter进行连接。
  2. 希望有一个类转换成另外一个类,但是两个类不兼容,又希望他们能一起工作,那就比较适合使用我们的适配器模式了,提高类的复用。

四. RecyclerView的适配器模式

我们看下面这张图,我们的app的列表是会有很多的数据,数据都是存在集合上面的,但是我们的数据,也就是我们的集合是不能直接添加到我们的ViewGroup上面去的,为什么说是ViewGroup呢,因为列表嘛,肯定不会只有一个子view,数据是不能直接通过addView的方式直接添加到我们的视图上面去显示的。

所以我们需要做一个中转,需要一个适配器Adapter,它做什么工作,它把数据给改了,把集合中的数据改成一个个对应的View,然后再把这些View,通过addView就可以添加到我们的视图上面去了,

接下来我们写个Demo,感受一下适配器:

测试用的Activity

public class TestActivity extends AppCompatActivity {private RecyclerView recyclerView;@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);recyclerView = findViewById(R.id.recyclerview);LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);recyclerView.setLayoutManager(linearLayoutManager);//构建源数据,List<String> data = new ArrayList<>();data.add("111");data.add("222");data.add("333");MyAdapter myAdapter = new MyAdapter(this, data);recyclerView.setAdapter(myAdapter);}
}

适配器

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {private Context mContext;private List<String> mData;public MyAdapter(Context mContext, List<String> mData) {this.mContext = mContext;this.mData = mData;}@NonNull@Overridepublic MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {View view = LayoutInflater.from(mContext).inflate(R.layout.item_test, parent, false);return new MyViewHolder(view);}@Overridepublic void onBindViewHolder(@NonNull MyViewHolder holder, int position) {String data = this.mData.get(position);holder.textView.setText(data);}@Overridepublic int getItemCount() {return mData.size();}public static class MyViewHolder extends RecyclerView.ViewHolder {TextView textView;public MyViewHolder(@NonNull View itemView) {super(itemView);textView = itemView.findViewById(R.id.textview);}}
}

item子view的xml布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android=""android:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="vertical"><TextViewandroid:id="@+id/textview"android:textSize="30sp"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="111" />
</LinearLayout>

父布局的xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android=""android:layout_width="match_parent"android:layout_height="match_parent"android:gravity="center"android:orientation="vertical"><androidx.recyclerview.widget.RecyclerViewandroid:id="@+id/recyclerview"android:layout_width="match_parent"android:layout_height="match_parent"/></LinearLayout>

最终的运行结果:

这就是一个经典的适配器模式的例子,也很常用,通过适配器将集合中的数据进行中转,再通过适配器addView。

五. 手写ListView体验适配器模式

我们手写自定义一个适配器,体验一下适配器模式的用途。

/*** 手写简单的ListView,不考虑复用*/
public class TestListView extends ScrollView {private LinearLayout mContainer;private ListAdapter mAdapter;public TestListView(Context context) {super(context, null);}public TestListView(Context context, AttributeSet attrs) {super(context, attrs, 0);mContainer = new LinearLayout(context);mContainer.setOrientation(LinearLayout.VERTICAL);super.addView(mContainer);}public TestListView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);mContainer = new LinearLayout(context);mContainer.setOrientation(LinearLayout.VERTICAL);super.addView(mContainer);}public void addView(View child) {mContainer.addView(child);}public void setAdapter(ListAdapter listAdapter) {this.mAdapter = listAdapter;int count = mAdapter.getCount();for (int i = 0; i < count; i++) {View childView = mAdapter.getView(i, mContainer);mContainer.addView(childView);}}
}

先自定义一个抽象类父类适配器,模拟ListView的两个方法,

public abstract class ListAdapter {//获取多少条public abstract int getCount();//获取Viewpublic abstract View getView(int position, ViewGroup viewGroup);
}

实现类

public class MyAdapter extends ListAdapter {private Context mContext;private List<String> mItems;public MyAdapter(Context mContext, List<String> mItems) {this.mContext = mContext;this.mItems = mItems;}@Overridepublic int getCount() {return mItems.size();}@Overridepublic View getView(int position, ViewGroup viewGroup) {TextView itemView = (TextView) LayoutInflater.from(mContext).inflate(R.layout.item_simple3, null);itemView.setText(mItems.get(position));return itemView;}
}

测试类

public class TestActivity extends AppCompatActivity {TestListView testListView;List<String> mData;@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);testListView = findViewById(R.id.testView);mData = new ArrayList<>();for (int i = 0; i < 100; i++) {mData.add(i + "");}MyAdapter myAdapter = new MyAdapter(this, mData);testListView.setAdapter(myAdapter);}
}

activity_main的xml布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android=""android:layout_width="match_parent"android:layout_height="match_parent"android:gravity="center"android:orientation="vertical"><com.example.myapplication.TestListViewandroid:id="@+id/testView"android:layout_width="match_parent"android:layout_height="match_parent"></com.example.myapplication.TestListView></LinearLayout>

itemView的xml布局

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android=""android:orientation="vertical"android:layout_width="match_parent"android:layout_height="wrap_content"></TextView>

测试结果

更多推荐

Android适配器模式,手写ListView体验适配器

本文发布于:2024-03-09 01:53:38,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1723313.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:适配器   模式   Android   ListView

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!