public class CommonAdapter extends BaseAdapter { private Context context; private Listlst; int layoutID; public CommonAdapter(Context context, List lstData, int layoutID) { this.context = context; this.lst = lstData; this.layoutID = layoutID; } public static class ViewHolder { public TextView Text; public TextView SubText; } public View getView(int position, View convertView, ViewGroup parent) { View v = convertView; ViewHolder viewHolder; if (v == null) { LayoutInflater inflater = (LayoutInflater) context .getSystemService(Context.LAYOUT_INFLATER_SERVICE); v = inflater.inflate(layoutID, parent, false); viewHolder = new ViewHolder(); viewHolder.Text = (TextView) v.findViewById(R.id.lstmText); viewHolder.SubText = (TextView) v.findViewById(R.id.lstmSub); v.setTag(viewHolder); } else { viewHolder = (ViewHolder) v.getTag(); } viewHolder.Text.setText(lst.get(position).Text); viewHolder.SubText.setText(lst.get(position).SubText); Static.setiFont(viewHolder.Text); Static.setiFont(viewHolder.SubText); return v; } public int getCount() { return lst.size(); } public Object getItem(int position) { return lst.get(position); } public long getItemId(int position) { return position; } public class CommonAdapterData { public int id; public String Text; public String SubText; } }
For many kinds of list view 's row (difference template), we have to create an suitable adapter.
Now, we have another way which can make your work is easy.
First, we need the interface define the way to build row view.
public interface Adaptable { public View buildView(View v, LayoutInflater inflater, ViewGroup parent); }
Then, we create a Generic adapter to use this interface above. There is no magic.
public class GenericAdapter extends BaseAdapter { private LayoutInflater inflater; private Listitems; @SuppressWarnings("unchecked") public GenericAdapter(List items, Context c) { this.items = (List ) items; inflater = LayoutInflater.from(c); } @Override public int getCount() { return items.size(); } @Override public Object getItem(int position) { return items.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { return items.get(position).buildView(convertView, inflater, parent); } }
After that, we create an view holder which holder the control in row view (TextView, ImageView, EditText...) and we will map it with an id by using annotation.
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface InvokeView { int viewId(); }Assume we have an entity:
public class Mobile { public String name; public int image; public Mobile(){} public Mobile(String name, int image){ this.name = name; this.image = image; } }Now we create an BaseView abstract class, which can be load row xml layout, map view id to viewhoder by using reflect.
public abstract class BaseViewThen we define how to map data from entity to the view through view holder. This is a sub class of BaseView.implements Adaptable{ private static final String TAG = "BaseView"; protected int layoutId; protected T viewHolder; protected E entity; public BaseView(){ } public BaseView(E entity, int layoutId){ this.entity = entity; this.layoutId = layoutId; } protected void invokeView(View v){ try { Field fs[] = viewHolder.getClass().getFields(); for (Field f : fs) { InvokeView a = (InvokeView) f.getAnnotation(InvokeView.class); int id = a.viewId(); Log.d(TAG, "field name: " + f.getName()); Log.d(TAG, "view id: " + id); Log.d(TAG, "class: " + f.getClass()); f.set(viewHolder, v.findViewById(id)); } } catch (Exception ex) { ex.printStackTrace(); } } @SuppressWarnings("unchecked") @Override public View buildView(View v, LayoutInflater inflater, ViewGroup parent) { // load the view if (null == v) { v = inflater.inflate(layoutId, parent, false); // get the view invokeView(v); v.setTag(viewHolder); } else { viewHolder = (T) v.getTag(); } // binding logic data to view mappingData(viewHolder, entity); return v; } protected abstract void mappingData(T viewHolder, E entity); }
public class MobileView extends BaseViewFinally, we can use our adapter for list view.{ public MobileView(Mobile mobile, int layoutId) { super(mobile, layoutId); this.viewHolder = new MobileViewHolder(); } @Override public void mappingData(MobileViewHolder viewHolder, Mobile entity) { viewHolder.text.setText(entity.name); viewHolder.image.setBackgroundResource(entity.image); } }
public class ListMobileActivity extends ListActivity { private static final int FRUIT_ID = 0; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ListAlso, I give an source code, which can be found herelst = new ArrayList (); for(int i = 0; i < 10; i++){ MobileView mv = new MobileView(new Mobile(String.valueOf(i), R.drawable.android_logo), R.layout.list_mobile); lst.add(mv); } setListAdapter(new GenericAdapter(lst, getApplicationContext())); } }