package org.edx.mobile.view.custom; import java.util.ArrayList; import java.util.List; import android.content.Context; import android.util.SparseIntArray; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView.OnItemClickListener; import android.widget.BaseAdapter; public abstract class BaseListAdapter<T> extends BaseAdapter implements OnItemClickListener { // constants that define selection state of list rows public static final int STATE_NOT_SELECTED = 0; public static final int STATE_SELECTED = 1; protected Context context; private List<T> items = new ArrayList<T>(); private SparseIntArray selection = new SparseIntArray(); public static final long MIN_CLICK_INTERVAL = 1000; //in millis public BaseListAdapter(Context context) { this.context = context; } /** * Selects the list row at specified position. * @param position */ public void select(int position) { selection.put(position, STATE_SELECTED); } /** * De-selects the list row at specified position. * @param position */ public void unselect(int position) { selection.put(position, STATE_NOT_SELECTED); } /** * Selects all the items in this adapter. */ public void selectAll() { for (int i=0; i<getCount(); i++) { select(i); } } /** * De-selects all the items from this adapter. */ public void unselectAll() { selection.clear(); } /** * Returns true if list row at specified position is selected, false otherwise. * @param position * @return */ public boolean isSelected(int position) { Integer val = selection.get(position); if (val == null) return false; return (val == STATE_SELECTED); } /** * Returns list of selected items. * @return */ public ArrayList<T> getSelectedItems() { ArrayList<T> selectedItems = new ArrayList<T>(); for (int i=0; i<getCount(); i++) { if (isSelected(i)) { selectedItems.add(getItem(i)); } } return selectedItems; } /** * Returns true if at least one item in the list is selected, false otherwise. * @return */ public boolean isAnythingSelected() { return (getSelectedItems().size() > 0); } /** * Adds given item to this adapter. * @param item */ public void add(T item) { items.add(item); } /** * Removes specified object from the adapter and returns success. * @param item * @return */ public boolean remove(T item) { return items.remove(item); } /** * Clears existing items from the adapter and sets given list as the data. * If null is provided, this method clears the existing values. * This avoids null value errors. * @param items */ public void setItems(List<T> items) { if (items == null) { this.items.clear(); } else { this.items = items; } this.selection.clear(); } /** * Clears all items from this adapter. */ public void clear() { items.clear(); selection.clear(); } @Override public int getCount() { return items.size(); } @Override public T getItem(int index) { return items.get(index); } public int getPosition(T item) { int pos = items.indexOf(item); return pos; } @Override public long getItemId(int index) { return index; } public List<T> getItems() { return items; } @Override public View getView(int position, View convertView, ViewGroup adapter) { try { if (convertView == null) { // create list row LayoutInflater inflator = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); convertView = inflator.inflate(getListItemLayoutResId(), null); // apply a tag to this list row BaseViewHolder tag = getTag(convertView); convertView.setTag(tag); } // get the tag for this list row BaseViewHolder tag = (BaseViewHolder) convertView.getTag(); // put position into the holder object tag.position = position; // get model data for this list row T model = items.get(position); // now render data for this list row render(tag, model); return convertView; } catch(Exception ex) { ex.printStackTrace(); } return convertView; } /** * Sub-class should override this method to render model's data to ViewHolder tag. * @param tag * @param model */ public abstract void render(BaseViewHolder tag, T model); /** * Sub-class should override this method and return ViewHolder tag that * is to be applied to the given convertView. * @param convertView * @return */ public abstract BaseViewHolder getTag(View convertView); /** * Sub-class should override this method to return layoutId of list item layout. * @return */ public abstract int getListItemLayoutResId(); /** * Base class for ViewHolders in individual adapters. */ public static class BaseViewHolder { public int position; public String videoId; } }