关于andriod的Adapter理解
Adapter
我们知道,数据源是各种各样的,而ListView所展示数据的格式则是有一定的要求的。数据适配器正是建立了数据源与ListView之间的适配关系,将数据源转换为ListView能够显示的数据格式,从而将数据的来源与数据的显示进行解耦,降低程序的耦合性。这也体现了Android的适配器模式的使用。常用的适配器是ArraryAdapter,BaseAdapter,SimpleAdapter等。因为ArraryAdapter 该适配器局限太大,故本文不与介绍。
ArraryAdapter
1.ArraryAdapter 类 原型
该类初始化函数复写多次
用于不同数据源的匹配格式,该适配器主要用于“一行”,主要使用list ,有别于SimpleAdapter,因为使用list的关系,导致该数据组的数据类型要一至,这就导致了拓展性较差。
public class ArrayAdapter<T> extends BaseAdapter implements Filterable, ThemedSpinnerAdapter{
/**
* Constructor
*
* @param context The current context.
* @param resource The resource ID for a layout file containing a layout to use when
* instantiating views.
* @param textViewResourceId The id of the TextView within the layout resource to be populated
* @param objects The objects to represent in the ListView.
*/
public ArrayAdapter(@NonNull Context context, @LayoutRes int resource) {
this(context, resource, 0, new ArrayList<>());
}
public ArrayAdapter(@NonNull Context context, @LayoutRes int resource,
@IdRes int textViewResourceId) {
this(context, resource, textViewResourceId, new ArrayList<>());
}
public ArrayAdapter(@NonNull Context context, @LayoutRes int resource, @NonNull T[] objects) {
this(context, resource, 0, Arrays.asList(objects));
}
public ArrayAdapter(@NonNull Context context, @LayoutRes int resource,
@IdRes int textViewResourceId, @NonNull T[] objects) {
this(context, resource, textViewResourceId, Arrays.asList(objects));
}
public ArrayAdapter(@NonNull Context context, @LayoutRes int resource,
@IdRes int textViewResourceId, @NonNull List<T> objects) {
this(context, resource, textViewResourceId, objects, false);
}
private ArrayAdapter(@NonNull Context context, @LayoutRes int resource,
@IdRes int textViewResourceId, @NonNull List<T> objects, boolean objsFromResources) {
mContext = context;
mInflater = LayoutInflater.from(context);
mResource = mDropDownResource = resource;
mObjects = objects;
mObjectsFromResources = objsFromResources;
mFieldId = textViewResourceId;
}
}
BaseAdapte
一般来讲使用BaseAdapte 都要自定义Adapate,因为该类的使用,需要实现把数据源确定,这样才能在匹配数据时,按照类的方式直接使用
事例一
2.BaseAdapter类 原型
public abstract class BaseAdapter implements ListAdapter, SpinnerAdapter
实例二(该类原型继承类)
该类没有原初始化函数 所以 一定要重载
public class MyAdapter extends BaseAdapter{
private List<ItemBean> mList;//数据源
private LayoutInflater mInflater;//布局装载器对象
// 通过构造方法将数据源与数据适配器关联起来
// context:要使用当前的Adapter的界面对象
public MyAdapter(Context context, List<ItemBean> list) {
mList = list;
mInflater = LayoutInflater.from(context);
}
@Override
//ListView需要显示的数据数量
public int getCount() {
return mList.size();
}
@Override
//指定的索引对应的数据项
public Object getItem(int position) {
return mList.get(position);
}
@Override
//指定的索引对应的数据项ID
public long getItemId(int position) {
return position;
}
@Override
//返回每一项的显示内容
public View getView(int position, View convertView, ViewGroup parent) {
//将布局文件转化为View对象
View view = mInflater.inflate(R.layout.item,null);
/**
* 找到item布局文件中对应的控件
*/
TextView titleTextView = (TextView) view.findViewById(R.id.tv_title);
TextView contentTextView = (TextView) view.findViewById(R.id.tv_content);
//获取相应索引的ItemBean对象
ItemBean bean = mList.get(position);
/**
* 设置控件的对应属性值
*/
titleTextView.setText(bean.itemTitle);
contentTextView.setText(bean.itemContent);
return view;
}
}
SimpleAdapter
事例三 SimpleAdapter原初始化类
public SimpleAdapter(Context context, List<? extends Map<String, ?>> data,
@LayoutRes int resource, String[] from, @IdRes int[] to) {
mData = data;
mResource = mDropDownResource = resource;
mFrom = from;
mTo = to;
mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
实列三 利用数据库直接获取数据源,因为SimpleAdapter原型 类似与BaseAdapter)
Cursor name=dataOperation.getAll();
while(name.moveToNext()){
Map<String, Object> items = new HashMap<String, Object>();
String notename1=name.getString(0);
notetitle.add(notename1);
String notetime1=name.getString(2);
items.put("notename1", notename1); //放入头像, 根据下标获取数组
items.put("notetime1", notetime1); //放入名字, 根据下标获取数组
list_map.add(items);
}
simpleAdapter = new SimpleAdapter(
MainActivity.this,
list_map,
R.layout.listnote_item,
new String[]{"notename1", "notetime1"},
new int[]{R.id.notename, R.id.notetime});
listView.setAdapter(simpleAdapter);
SimpleAdapter与BaseAdapte的区别
它们两都是Android里的适配器,充当数据和界面之间的桥梁,用SimpleAdapter、baseAdapter的实现效果都几乎是一样,SimpleAdapter适配器使用的数据结构是HashMap,这意味着,如果需要操作的数据对象结构过于复杂时,需要写大量的相关转化代码,程序的效率和可维护性都会变的很低,但是它完全不用考虑缓存弄到应用程序卡死的问题,而且代码会与页面代码耦合,无法切换页面,反过来baseAdapter却是需要写清除缓存代码的,而且baseadapter代码会相对来说会简洁清晰页面与代码不会耦合,所以使用baseadapter会让代码变得简捷效率更加灵活操作
#SimpleAdapter实例
lists = new ArrayList<>();
for(int i = 0;i < theme.length;i++){
Map<String,Object> map =new HashMap<>();
map.put("image",imageViews[i]);
map.put("theme",theme[i]);
map.put("content",content[i]);
lists.add(map);
}
adapter = new SimpleAdapter(MainActivity.this,lists,R.layout.list_item
,new String[]{"image","theme","content"}
,new int[]{R.id.image1,R.id.text1,R.id.text2});
listView.setAdapter(adapter);
#BaseAdapter实例
lists = new ArrayList<>();
lists.add(new Message(R.mipmap.zhang,"张三","你好,我是张三"));
lists.add(new Message(R.mipmap.lisi,"李四","你好,我是李四"));
lists.add(new Message(R.mipmap.wu,"王五","你好,我是王五"));
adapter = new MyAdapter(lists,MainActivity.this);
listView.setAdapter(adapter);
例子里面可以清楚看到2种Adapter区别,BaseAdapter遇到复杂数据源直接重构Adapter又因为该函数原型没有BaseAdapter()初始化函数,所以一定要复写初始化函数,无法直接使用默认函数。SimpleAdapter则不同,该类有初始化函数,且该初始化函数含有hashmap,当然
public SimpleAdapter(Context context, List<? extends Map<String, ?>> data,
@LayoutRes int resource, String[] from, @IdRes int[] to)
可以重载该该初始化函数,当然这个重载也有局限性。我们不同情况可以分别使用不同的Adapter,当你的数据源较之比较简单,且格式不复杂,或者说数据处理不复杂的话,使用SImaple可以减轻你的工作量。当你的使用比较大的,且复杂的数据源时,强烈建议使用BaseAdaoter,该类可以重写初始化函数,且可以减少代码量和更加灵活。