码迷,mamicode.com
首页 > 移动开发 > 详细

Android适配器之基于BaseAdapter定义AbslistView万能适配器

时间:2016-08-23 21:50:31      阅读:226      评论:0      收藏:0      [点我收藏+]

标签:

为统一数据相关操作,现给出数据处理相关操作的接口定义,其中包含对列表数据的增删改查等常规操作。
/**
* Created by Administrator on 2016/4/19.
* 适配器的数据修改方法的定义
*/
public interface IAdapterDataModifyHelper<T> {
/**
* 通知适配器更新界面
*
* @param INotifyDataSetChange
*/
void setNotifyAdapterDataSetChange(INotifyAdapterDataSetChange INotifyDataSetChange);

/**
* 获取数据集
*
* @return
*/
List<T> getDataResources();


/**
* 设置数据集
*
* @param dataResources
*/
void setDataResource(T... dataResources);

void setDataResource(List<? extends T> dataResource);

/**
* 添加数据
*
* @param location
* @param dataResources
*/
void addDataResource(int location, T... dataResources);

void addDataResource(int location, List<? extends T> dataResources);

void addFirstDataResource(T... dataResources);

void addFirstDataResource(List<T> dataResources);

void addEndDataResource(T... dataResources);

void addEndDataResource(List<T> dataResources);

/**
* 修改元素
*
* @param position
* @param enity
*/
void reviseDataResource(int position, T enity);

/**
* 移除指定元素
*/
void removeDataResource(T removedEntiy);

/**
* 移除指定位置的元素
*
* @param position
*/
void removeDataResourceOnPosition(int position);

/**
* 清空所有数据集
*/
void clear();

/**
* 修正带操作的数据索引下标
*
* @param location
* @return
*/
int proofOperateDataLocation(int location);

/**
* 判断操作的location位置是否正确
*
* @return
*/
boolean isOperateLocationRight(int position);
}
IAdapterDataModifyHelper的实现类DataModifyHelper的部分源码如下:
/**
* @Description:针对数据的相关处理Helper类
* @author: Xiaoxuan948
* @date: 2016/7/20 20:37
*/
public class DataModifyHelper<T> implements IAdapterDataModifyHelper<T> {
private final UtilsLog lg = UtilsLog.getLogger(DataModifyHelper.class);
protected List<T> mDataResources;
private INotifyAdapterDataSetChange INotifyDataSetChange;

public DataModifyHelper() {
this.mDataResources = new ArrayList<>();
}

@Override
public void setNotifyAdapterDataSetChange(INotifyAdapterDataSetChange INotifyDataSetChange) {
this.INotifyDataSetChange = INotifyDataSetChange;
}

@Override
public List<T> getDataResources() {
return mDataResources;
}

@Override
public void setDataResource(List<? extends T> setDataResources) {
/*针对集合空数据进行处理*/
if (UtilsCollections.isCollectionNotEmpty(setDataResources) && setDataResources.contains(null)) {
lg.e("setDataResource集合包含null数据");
setDataResources = Lists.newArrayList(Collections2.filter(setDataResources, new Predicate<T>() {
@Override
public boolean apply(T input) {
return input != null;
}
}));
}
if (!UtilsCollections.isCollectionNotEmpty(setDataResources)) {
return;
}
/*针对类型不匹配进行处理*/
this.mDataResources = Lists.transform(setDataResources, new Function<Object, T>() {
@Override
public T apply(Object input) {
return (T) input;
}
});
INotifyDataSetChange.notifyAdapter();
}

@Override
public void addDataResource(int location, List<? extends T> addDataResources) {
if (UtilsCollections.isCollectionNotEmpty(addDataResources) && addDataResources.contains(null)) {
lg.e("addDataResource集合包含null数据");
addDataResources = Lists.newArrayList(Collections2.filter(addDataResources, new Predicate<T>() {
@Override
public boolean apply(T input) {
return input != null;
}
}));
}
if (!UtilsCollections.isCollectionNotEmpty(addDataResources)) {
lg.e("addDataResource:待加入的集合为空");
return;
}
location = proofOperateDataLocation(location);
this.mDataResources.addAll(location, addDataResources);
INotifyDataSetChange.notifyAdapter();
}

@Override
public void reviseDataResource(int position, T enity) {
if (isOperateLocationRight(position)) {
this.mDataResources.set(position, enity);
INotifyDataSetChange.notifyAdapter();
} else {
lg.e("reviseDataResource failed because position out of size " + this.mDataResources.size());
}
}

@Override
public void removeDataResourceOnPosition(int position) {
this.mDataResources.remove(position);
INotifyDataSetChange.notifyAdapter();
}

@Override
public void clear() {
this.mDataResources.clear();
INotifyDataSetChange.notifyAdapter();
}

@Override
public boolean isOperateLocationRight(int position) {
return !(position < 0 || position > this.mDataResources.size());
}

@Override
public int proofOperateDataLocation(int location) {
int newLocation = location < 0 ? 0 : location > this.mDataResources.size() ? this.mDataResources.size() : location;
lg.e("proofOperateDataLocation from " + location + " to " + newLocation);
return newLocation;
}
}
观察可知,在DataModifyHelper构造函数中实例化mDataResources对象,其对应于列表控件中显示的数据。
setNotifyAdapterDataSetChange为外界提供数据更新的接口注入方法,在数据修改后调用INotifyDataSetChange的notifyAdapter()方法即可通知适配器更新。
setDataResource方法中,针对List数据先进行非空过滤,再判断List非空后进行数据修改,以确保mDataResources集合始终非空。这里会注意到其参数使用无限制通配符,这里是提高程序扩展性,当适配器基于接口编程时能方便set数据。(提示:List<Child>无法转为List<Parent>)
addDataResource的实现过程同setDataResource基本一致,都是针对数据集进行非空等一系列处理。
 
接下来考虑定义BaseAdapter抽象基类,抽取共性部分,即实现getCount、getItem、getItemId
观察源码可知,在构造函数中实例化DataModifyHelper对象,该对象负责数据的增删改查等操作。适配器中提供getDataModifyHelper方法,供外界获得操作数据的DataModifyHelper帮助类。
public abstract class AbsUnityBaseAdapter<T> extends BaseAdapter implements INotifyAdapterDataSetChange {
private static final UtilsLog lg = UtilsLog.getLogger(AbsUnityBaseAdapter.class);
private LayoutInflater layoutInflater;
private IAdapterDataModifyHelper<T> IAdapterataModifyHelper;

/**
* 构造方法
*/
protected AbsUnityBaseAdapter() {
this.IAdapterataModifyHelper = new DataModifyHelper<>();
}

public IAdapterDataModifyHelper<T> getDataModifyHelper() {
this.IAdapterataModifyHelper.setNotifyAdapterDataSetChange(this);
return IAdapterataModifyHelper;
}

@Override
public void notifyAdapter() {
notifyDataSetChanged();
}

/**
* default method
*/
@Override
public int getCount() {
return IAdapterataModifyHelper.getDataResources().size();
}

@Override
public T getItem(int position) {
//可能数组越界
if (position >= IAdapterataModifyHelper.getDataResources().size()) {
lg.e("getItem:index " + position + " is out of size " + IAdapterataModifyHelper.getDataResources().size());
return null;
}
return IAdapterataModifyHelper.getDataResources().get(position);
}

@Override
public long getItemId(int position) {
return position;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
UnityAdapterViewHolder helper = null;
if (convertView != null) {
helper = (UnityAdapterViewHolder) convertView.getTag();
} else {
if (layoutInflater == null) {
layoutInflater = LayoutInflater.from(parent.getContext());
}
helper = new UnityAdapterViewHolder(layoutInflater, getLayoutId(), parent);
}
convert(IAdapterataModifyHelper.getDataResources().get(position), helper, position);
return helper.getConvertView();
}

/*自定义抽象方法*/
public abstract void convert(T itemEntity, UnityAdapterViewHolder helper, int position);

public abstract int getLayoutId();
}
分析getView部分源码可知,其基于UnityAdapterViewHolder类封装ViewHolder模式,构造方法如下:
/**
* Created by Administrator on 2015/8/25.
*/
public class UnityAdapterViewHolder {
private SparseArray<View> views;
private View convertView;

public UnityAdapterViewHolder(LayoutInflater layoutInflater, int layoutId, ViewGroup parent) {
this.views = new SparseArray<>();
this.convertView = layoutInflater.inflate(layoutId, parent, false);
this.convertView.setTag(this);
}

public View getConvertView() {
return convertView;
}

/**
* generateView
*
* @param viewId
* @param <T>
* @return
*/
protected <T extends View> T generateView(int viewId) {
View view = views.get(viewId);
if (view == null) {
view = convertView.findViewById(viewId);
views.put(viewId, view);
}
return (T) view;
}

/**
* @param viewId
* @param clz
* @param <T>
* @return
*/
public <T extends View> T generateView(int viewId, Class<T> clz) {
return generateView(viewId);
}
}
业务层使用方式如下:
adapter = new AbsUnityBaseRecyclerAdapter<CorePageEntity>() {
@Override
public void convert(CorePageEntity itemEntity, UnityRecyclerAdapterViewHolder viewHolder, int position) {
viewHolder.generateView(R.id.tvItemCommon, TextView.class).setText(itemEntity.getCorePageTitle());
}

@Override
public int getItemLayoutId(int viewType) {
return R.layout.simple_item_horizontal;
}
};
对于数据修改等操作,
adapter.getDataModifyHelper().setDataResource(
CorePageEntity.create(TestActivity.class),
CorePageEntity.create(PullToRefreshActivity.class)
);
 
 
 





Android适配器之基于BaseAdapter定义AbslistView万能适配器

标签:

原文地址:http://www.cnblogs.com/linux007/p/5800905.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!