package co.infinum.ava;
import android.app.Activity;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import java.lang.reflect.Method;
import java.util.ArrayList;
/**
* Adapter that can be injected with views using AbstractViewHolder.
*
* Created by ivan on 12/15/13.
*/
public class AbstractViewAdapter<T> extends ArrayAdapter<T> {
protected static final String INJECTOR_CLASS_NAME_SUFIX = "$$AdapterInjector";
protected static final String INJECTOR_METHOD_NAME = "inject";
/**
* Factory for creating abstract view holders.
*/
protected AbstractViewHolder.Factory<T> abstractViewFactory;
/**
* Used to store current abstract view holder.
*/
private AbstractViewHolder<T> abstractViewHolder;
/**
* Creates new AbstractViewAdapter.
*
* @param context
* @param abstractViewFactory
* @param items
*/
public AbstractViewAdapter(Context context, AbstractViewHolder.Factory<T> abstractViewFactory, ArrayList<T> items) {
super(context, 0, items);
this.abstractViewFactory = abstractViewFactory;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView == null) {
abstractViewHolder = abstractViewFactory.createView(getContext());
convertView = abstractViewHolder.updateView(getItem(position));
convertView.setTag(abstractViewHolder);
} else {
abstractViewHolder = (AbstractViewHolder<T>)convertView.getTag();
abstractViewHolder.updateView(getItem(position));
return convertView;
}
return convertView;
}
public static void injectAdapters(Activity activity) {
String injectorClassName = activity.getClass().getName() + INJECTOR_CLASS_NAME_SUFIX;
try {
Object injectorObject = Class.forName(injectorClassName).newInstance();
Method method = getActivityInjectMethod(injectorObject, activity);
method.invoke(injectorObject, activity);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void injectAdapters(Object object, View rootView) {
String injectorClassName = object.getClass().getName() + INJECTOR_CLASS_NAME_SUFIX;
try {
Object injectorObject = Class.forName(injectorClassName).newInstance();
Method method = getObjectInjectMethod(injectorObject, object);
method.invoke(injectorObject, object, rootView);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Returns method for activity injection.
*
* @param injectorObject
* @param activity
* @return
* @throws NoSuchMethodException
*/
private static Method getActivityInjectMethod(Object injectorObject, Activity activity) throws NoSuchMethodException {
Class[] parameterTypes = new Class[] {
activity.getClass()
};
return injectorObject.getClass().getMethod(INJECTOR_METHOD_NAME, parameterTypes);
}
/**
* Returns method for object injection.
*
* @param injectorObject
* @param object
* @return
* @throws NoSuchMethodException
*/
private static Method getObjectInjectMethod(Object injectorObject, Object object) throws NoSuchMethodException {
Class[] parameterTypes = new Class[] {
object.getClass(),
View.class
};
return injectorObject.getClass().getMethod(INJECTOR_METHOD_NAME, parameterTypes);
}
}