LIBBaseAdapter.java
8.4 KB
package com.xdy.commonlibrary.adapter;
import android.os.Handler;import android.os.Looper;import android.support.annotation.NonNull;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;
import com.xdy.commonlibrary.mvp.BasePresenter;
import java.lang.ref.WeakReference;import java.util.ArrayList;import java.util.Collection;import java.util.List;
/**
* <pre>
* 千万不要重载{@link LIBBaseAdapter#getView(int, View, ViewGroup)}
* </pre>
* @author lixi
* @Description <通用的Adapter>
* @date 2017-5-19
*/public abstract class LIBBaseAdapter<T, P extends BasePresenter> extends BaseAdapter implements LIBViewHolder.OnDatasetChangeListener {
protected List<T> mData;
protected WeakReference<P> mPresenter;
private Handler uiHandler;
public void setPresenter(P presenter) {
this.mPresenter = new WeakReference<>(presenter);
}
protected synchronized final Handler getHandler() {
if (uiHandler == null) {
uiHandler = new Handler(Looper.getMainLooper());
}
return uiHandler;
}
public LIBBaseAdapter() {
this(null);
}
public LIBBaseAdapter(List<T> list) {
if (list == null) {
mData = new ArrayList<T>();
} else {
mData = list;
}
init();
}
protected void init() {
}
/**
* 直接使用外部的List,自动调用notifyDataSetChanged
*/
public void setData(@NonNull List<T> list) {
mData = list;
notifyDataSetChanged();
}
public List<T> getList() {
return mData;
}
/**
* 添加数据 ,自动调用notifyDataSetChanged
*/
public boolean addData(Collection<? extends T> collection) {
return addData(collection, false);
}
/**
* 如果是第一笔数据,则会清空之前数据,自动调用notifyDataSetChanged
*/
public boolean addData(Collection<? extends T> collection, boolean isFirstData) {
if (null == collection || collection.isEmpty()) {
return false;
}
if (isFirstData) {
mData.clear();
}
mData.addAll(collection);
notifyDataSetChanged();
return true;
}
/**
* 添加1个数据,自动调用notifyDataSetChanged
*/
public void addData(T data) {
mData.add(data);
notifyDataSetChanged();
}
/**
* 移除1个数据,自动调用notifyDataSetChanged
*/
public T remove(int index) {
T t = this.mData.remove(index);
notifyDataSetChanged();
return t;
}
/**
* 移除1个数据,外部调用notifyDataSetChanged,需重载 {@link Object#equals(Object)}
*/
public T remove(Object object) {
if (null == object) {
return null;
}
for (int i = 0, size = null == mData ? 0 : mData.size(); i < size; i++) {
T t = mData.get(i);
if (null != t && t.equals(object)) {
return mData.remove(i);
}
}
return null;
}
/**
* 添加数据,自动调用notifyDataSetChanged
*/
public void addData(int position, T data) {
mData.add(position, data);
notifyDataSetChanged();
}
/**
* 添加数据,自动调用notifyDataSetChanged
*/
public boolean addData(int position, Collection<? extends T> collection) {
if (null == collection || collection.isEmpty()) {
return false;
}
mData.addAll(position, collection);
notifyDataSetChanged();
return true;
}
/**
* 清空数据,自动调用notifyDataSetChanged
*/
public void clear() {
mData.clear();
notifyDataSetChanged();
}
@Override
public int getCount() {
return mData.size();
}
public int getSize() {
return mData.size();
}
@Override
public T getItem(int position) {
return mData.get(position);
}
/**
* 获得某个item,需重载 {@link Object#equals(Object)}
*/
public T getItem(Object object) {
if (object == null) {
return null;
}
for (int i = 0, size = null != mData ? mData.size() : 0; i < size; i++) {
T t = getItem(i);
if (null != t && t.equals(object)) {
return t;
}
}
return null;
}
public T getLastItem() {
return mData.get(mData.size() - 1);
}
@Override
public long getItemId(int position) {
return position;
}
private ArrayList<LIBViewHolder> holders = new ArrayList<LIBViewHolder>();
private LIBViewHolder getHolder(Object data) {
if (null == data) {
return null;
}
for (int i = 0, size = holders.size(); i < size; i++) {
LIBViewHolder holder = holders.get(i);
if (holder.equals(data)) {
return holder;
}
}
return null;
}
@Override
public final void onChange(final LIBViewHolder holder) {
if (Looper.myLooper() != Looper.getMainLooper()) {// 如果不是主线程,就交给Handler做处理
getHandler().post(new Runnable() {
@Override
public void run() {
onChange(holder);
}
});
return;
}
T data = holder.getTag();
holder.markRecyclerHolder();// 标记当前是重用状态
convert(holder, data, holder.getItemViewType(), holder.getPosition());// 转换布局
holder.resetRecyclerHolder();// 重置标记
}
@Override
public final synchronized void notifyDataSetChanged() {
if (Looper.myLooper() != Looper.getMainLooper()) {// 如果不是主线程,就交给Handler做处理
getHandler().post(new Runnable() {
@Override
public void run() {
LIBBaseAdapter.super.notifyDataSetChanged();
}
});
return;
} else {
super.notifyDataSetChanged();
}
}
/**
* 刷新Item,需重写 {@link Object#equals(Object)}
*/
public final synchronized void refreshItem(final Object item) {
LIBViewHolder holder = getHolder(item);// 查找Holder,根据Holder缓存的Tag和当前传入的item匹配
if (null == holder) {// 如果找不到Holder,则刷新全部
notifyDataSetChanged();
return;
} else {
onChange(holder);
return;
}
}
private static final int FLAG_NONE = 0;
private static final int FLAG_BASE_ENTITY = 1;
private static final int FLAG_OTHER_ENTITY = 2;
private int mFlag = FLAG_NONE;
public void setNoRecycleFlag(boolean mNoRecycleFlag) {
this.mNoRecycleFlag = mNoRecycleFlag;
}
private boolean mNoRecycleFlag = false;//不回收标示默认为FALSE
@Deprecated
@Override
public View getView(int position, View convertView, ViewGroup parent) {
T data = getItem(position);
int itemViewType = getItemViewType(position);
LIBViewHolder holder = LIBViewHolder.getHolder(convertView, parent, getLayoutId(data, itemViewType, position), position, itemViewType, mNoRecycleFlag);
setTag(data, holder);
if (!holder.isRecyleHolder()) {
holders.add(holder);// 缓存Holder
holder.setListener(this);// 设置刷新监听
}
convert(holder, data, itemViewType, position);// 回调UI
return holder.getConvertView();// 返回主布局,即ConvertView
}
private final void setTag(T data, LIBViewHolder holder) {
switch (mFlag) {
case FLAG_NONE:
if (data instanceof LIBBaseEntity) {
((LIBBaseEntity) data).registerObserver(holder);
mFlag = FLAG_BASE_ENTITY;
} else {
mFlag = FLAG_OTHER_ENTITY;
}
break;
case FLAG_BASE_ENTITY:
((LIBBaseEntity) data).registerObserver(holder);
break;
default:
break;
}
holder.setTag(data);
}
/**
* 转换布局
*/
public abstract void convert(LIBViewHolder holder, T data, int itemViewType, int position);
/**
* 获取布局id
*/
public abstract int getLayoutId(T data, int itemViewType, int position);
}