package in.srain.cube.views.list;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import in.srain.cube.util.CLog;
import in.srain.cube.util.Debug;
import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
/**
* A adapter using View Holder to display the item of a list view;
*
* @param <ItemDataType>
* @author http://www.liaohuqiu.net
*/
public abstract class ListViewDataAdapterBase<ItemDataType> extends BaseAdapter {
private static String LOG_TAG = "cube_list";
protected ViewHolderCreator<ItemDataType> mViewHolderCreator;
protected ViewHolderCreator<ItemDataType> mLazyCreator;
protected boolean mForceCreateView = false;
public ListViewDataAdapterBase() {
}
public ListViewDataAdapterBase(final Object enclosingInstance, final Class<?> cls) {
setViewHolderClass(enclosingInstance, cls);
}
/**
* @param viewHolderCreator The view holder creator will create a View Holder that extends {@link ViewHolderBase}
*/
public ListViewDataAdapterBase(ViewHolderCreator<ItemDataType> viewHolderCreator) {
mViewHolderCreator = viewHolderCreator;
}
public void setViewHolderCreator(ViewHolderCreator<ItemDataType> viewHolderCreator) {
mViewHolderCreator = viewHolderCreator;
}
public void setViewHolderClass(final Object enclosingInstance, final Class<?> cls) {
if (cls == null) {
throw new IllegalArgumentException("ViewHolderClass is null.");
}
mLazyCreator = new ViewHolderCreator<ItemDataType>() {
@Override
public ViewHolderBase<ItemDataType> createViewHolder() {
Object object = null;
try {
// top class
if (cls.getEnclosingClass() == null) {
Constructor<?> constructor = cls.getDeclaredConstructor();
constructor.setAccessible(true);
object = constructor.newInstance();
} else {
if (Modifier.isStatic(cls.getModifiers())) {
Constructor<?> constructor = cls.getDeclaredConstructor();
constructor.setAccessible(true);
object = constructor.newInstance();
} else {
Constructor<?> constructor = cls.getDeclaredConstructor(enclosingInstance.getClass());
constructor.setAccessible(true);
object = constructor.newInstance(enclosingInstance);
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
if (object == null || !(object instanceof ViewHolderBase)) {
throw new IllegalArgumentException("ViewHolderClass can not be initiated");
}
return (ViewHolderBase<ItemDataType>) object;
}
};
}
private ViewHolderBase<ItemDataType> createViewHolder() {
if (mViewHolderCreator == null && mLazyCreator == null) {
throw new RuntimeException("view holder creator is null");
}
if (mViewHolderCreator != null) {
return mViewHolderCreator.createViewHolder();
}
if (mLazyCreator != null) {
return mLazyCreator.createViewHolder();
}
return null;
}
public void forceCreateView(boolean yes) {
mForceCreateView = yes;
}
@SuppressWarnings("unchecked")
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (Debug.DEBUG_LIST) {
CLog.d(LOG_TAG, "getView %s", position);
}
ItemDataType itemData = getItem(position);
ViewHolderBase<ItemDataType> holderBase = null;
if (mForceCreateView || convertView == null || (!(convertView.getTag() instanceof ViewHolderBase<?>))) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
holderBase = createViewHolder();
if (holderBase != null) {
convertView = holderBase.createView(inflater);
if (convertView != null) {
if (!mForceCreateView) {
convertView.setTag(holderBase);
}
}
}
} else {
holderBase = (ViewHolderBase<ItemDataType>) convertView.getTag();
}
if (holderBase != null) {
holderBase.setItemData(position, convertView);
holderBase.showData(position, itemData);
}
return convertView;
}
@Override
public abstract ItemDataType getItem(int position);
}