这篇文章主要讲解了“Android如何实现自定义可复用的BaseAdapter”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Android如何实现自定义可复用的BaseAdapter”吧!
项目结构设计
UI端的设计
Android的开发我发觉历年的指导开发学习的过程有一个特性,它和后台、微服务的开发其实是一个思路。即:先设计模型(DB、MONGO、REDIS)、数据流存取再做代码设计才能往往想得更周到。此处的UI指的就是我们的布局、界面长什么。根据布局、界面长什么样,然后倒推我们的后端代码,往往更容易入门、入手。
带有GridView布局的activity_main.xml
这是一个一行三列布局的Grid
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="5dp" tools:context=".MainActivity"> <!--numColumns设置每行显示多少个--> <GridView android:id="@+id/gridPhoto" android:layout_width="match_parent" android:layout_height="match_parent" android:numColumns="3" /> </RelativeLayout>
带有GridView里显示明显控件的item_list.xml
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="5dp"> <ImageView android:id="@+id/iconImg" android:layout_width="64dp" android:layout_height="64dp" android:layout_centerInParent="true" android:src="@drawable/icon_1_128" /> <TextView android:id="@+id/iconText" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/iconImg" android:layout_centerHorizontal="true" android:layout_marginTop="30dp" android:text="text" android:textSize="18sp" /> </RelativeLayout>
可复用的Adapter的代码设计
我们使用我们一惯的风格,先用逻辑性的语言来描述这个类的设计。各位一定要养成这样的一个习惯,即OOP编程它本身就是用代码来实现现实世界事物用的。因此在现实世界可以用逻辑、抽象、总结后的事物再去用OOP语言实现往往来得更直观、更友好、可读性更好。
这个Adapter因为是可复用的,因此我们把它定义成Abstract,当然它也是extends自BaseAdapter;
这个类需要可以接受通用的业务(View)Bean,因此它必须可以支持传入泛型即<T>;
这个类需要可以接受各种控件,我们知道其实Adapter的inflate渲染函数传入的控件是控件的ID,如何获取控件的ID我们也已经知道了,它是一个int值;
由于这个可复用的Adapter需要一个个对传入的控件做处理,因此这个Adapter的getItem(int position)就不能再像前几章所讲的那样return null了,而是要return data.get(position);
在getView方法内由于我们传入的控件为“调用端”去“客制”,因此我们在这个getView内原本写死的viewHolder.控件.set属性(属性值)的控制权要放给到调
用端,因此我们在getView里做一个“匈牙利勾子”写法,即设一个bindView方法,同时把这个bindView做成abstract方法;
下面我们来看这个Abstract类的完整写法
可复用的Adapter-GenericAdapter
package org.mk.android.demogreidview; import android.content.Context;import android.util.Log;import android.util.SparseArray;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.ImageView;import android.widget.TextView; import java.util.ArrayList;import java.util.List; public abstract class GenericAdapter <T> extends BaseAdapter { private List<T> data; private int layoutRes; public GenericAdapter() { } public GenericAdapter(List<T> data, int layoutRes) { this.data = data; this.layoutRes = layoutRes; } @Override public int getCount() { Log.i("app",">>>>>>data.size: "+data.size()); if(data!=null) { return data.size(); } return 0; } @Override public T getItem(int position) { return data.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { Log.i("app",">>>>>>into getView"); ViewHolder holder = ViewHolder.bind(parent.getContext(), convertView, parent, layoutRes , position); bindView(holder, getItem(position)); return holder.getItemView(); } //添加一个元素 public void add(T item) { if (data == null) { data = new ArrayList<>(); } data.add(item); notifyDataSetChanged(); } //往特定位置,添加一个元素 public void add(int position,T item){ if (data == null) { data = new ArrayList<>(); } data.add(position, item); notifyDataSetChanged(); } public void remove(T item) { if(data != null) { data.remove(item); } notifyDataSetChanged(); } public void remove(int position) { if(data != null) { data.remove(position); } notifyDataSetChanged(); } public void clear() { if(data != null) { data.clear(); } notifyDataSetChanged(); } public abstract void bindView(ViewHolder holder, T obj); public static class ViewHolder { private SparseArray<View> mViews; //存储ListView 的 item中的View private View item; //存放convertView private int position; //游标 private Context context; //Context上下文 //构造方法,完成相关初始化 private ViewHolder(Context context, ViewGroup parent, int layoutRes) { mViews = new SparseArray<>(); this.context = context; View convertView = LayoutInflater.from(context).inflate(layoutRes, parent,false); convertView.setTag(this); item = convertView; } public static ViewHolder bind(Context context, View convertView, ViewGroup parent, int layoutRes, int position) { ViewHolder holder; if(convertView == null) { holder = new ViewHolder(context, parent, layoutRes); } else { holder = (ViewHolder) convertView.getTag(); holder.item = convertView; } holder.position = position; return holder; } public <T extends View> T getView(int id) { T t = (T) mViews.get(id); if(t == null) { t = (T) item.findViewById(id); mViews.put(id, t); } return t; } public View getItemView() { return item; } public int getItemPosition() { return position; } public ViewHolder setText(int id, CharSequence text) { View view = getView(id); if(view instanceof TextView) { ((TextView) view).setText(text); } return this; } public ViewHolder setImageResource(int id, int drawableRes) { View view = getView(id); if(view instanceof ImageView) { ((ImageView) view).setImageResource(drawableRes); } else { view.setBackgroundResource(drawableRes); } return this; } public ViewHolder setTag(int id, Object obj) { getView(id).setTag(obj); return this; } public ImageView iconImg; public TextView iconText; }}
业务(ViewBean)Bean-IconBean
package org.mk.android.demogreidview; import java.io.Serializable; public class IconBean implements Serializable { public IconBean(int imgId, String iconText) { this.imgId = imgId; this.iconText = iconText; } private int imgId; private String iconText = ""; public int getImgId() { return imgId; } public void setImgId(int imgId) { this.imgId = imgId; } public String getIconText() { return iconText; } public void setIconText(String iconText) { this.iconText = iconText; }}
主交互端-MainActivity
package org.mk.android.demogreidview; import androidx.appcompat.app.AppCompatActivity; import android.content.Context;import android.os.Bundle;import android.util.Log;import android.widget.BaseAdapter;import android.widget.GridView; import java.util.ArrayList;import java.util.List; public class MainActivity extends AppCompatActivity { private Context ctx; private GridView gridPhoto; private BaseAdapter adapter = null; private List<IconBean> data = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); gridPhoto = (GridView) findViewById(R.id.gridPhoto); data = new ArrayList<IconBean>(); data.add(new IconBean(R.drawable.icon_1_128, "图标1")); data.add(new IconBean(R.drawable.icon_2_128, "图标2")); data.add(new IconBean(R.drawable.icon_3_128, "图标3")); data.add(new IconBean(R.drawable.icon_4_128, "图标4")); data.add(new IconBean(R.drawable.icon_5_128, "图标5")); data.add(new IconBean(R.drawable.icon_6_128, "图标6")); data.add(new IconBean(R.drawable.icon_7_128, "图标7")); adapter = new GenericAdapter<IconBean>(data, R.layout.item_list) { @Override public void bindView(ViewHolder holder, IconBean obj) { holder.setImageResource(R.id.iconImg, obj.getImgId()); holder.setText(R.id.iconText, obj.getIconText()); } }; Log.i("app",">>>>>>before display"); gridPhoto.setAdapter(adapter); }}
感谢各位的阅读,以上就是“Android如何实现自定义可复用的BaseAdapter”的内容了,经过本文的学习后,相信大家对Android如何实现自定义可复用的BaseAdapter这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是编程网,小编将为大家推送更多相关知识点的文章,欢迎关注!