Back to project page ElyTheme.
The source code is released under:
GNU General Public License
If you think the Android project ElyTheme listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.
package com.afollestad.silk.adapters; //w w w. j a va2 s .c o m import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.AbsListView; import android.widget.BaseAdapter; import com.afollestad.silk.SilkComparable; import java.util.*; /** * A BaseAdapter wrapper that makes creating list adapters easier. Contains various convenience methods and handles * recycling views on its own. * * @param <ItemType> The type of items held in the adapter. * @author Aidan Follestad (afollestad) */ public abstract class SilkAdapter<ItemType extends SilkComparable> extends BaseAdapter implements ScrollStatePersister { private final Context context; private final List<ItemType> mItems; private boolean isChanged = false; private int mScrollState = AbsListView.OnScrollListener.SCROLL_STATE_IDLE; public SilkAdapter(Context context) { this.context = context; this.mItems = new ArrayList<ItemType>(); } private ItemType assignId(ItemType item) { if (getCount() == 0) item.setSilkId(1); else item.setSilkId(getItem(getCount() - 1).getSilkId() + 1); return item; } /** * Called to get the layout of a view being inflated by the SilkAdapter. The inheriting adapter class must return * the layout for list items, this should always be the same value unless you have multiple view types. * <p/> * If you override {#getItemViewType} and/or {#getViewTypeCount}, the parameter to this method will be filled with * the item type at the index of the item view being inflated. Otherwise, it can be ignored. */ protected abstract int getLayout(int index, int type); /** * Called when a list item view is inflated and the inheriting adapter must fill in views in the inflated layout. * The second parameter ('recycled') should be returned at the end of the method. * * @param index The index of the inflated view. * @param recycled The layout with views to be filled (e.g. text views). * @param item The item at the current index of the adapter. */ public abstract View onViewCreated(int index, View recycled, ItemType item); /** * Gets the context passed in the constructor, that's used for inflating views. */ protected final Context getContext() { return context; } /** * Adds an item at a specific index inside the adapter. */ public void add(int index, ItemType toAdd) { isChanged = true; this.mItems.add(index, assignId(toAdd)); notifyDataSetChanged(); } /** * Adds a list of items to the adapter and notifies the attached Listview. * * @param index The index to begin adding items at (inserted starting here). * @param toAdd The items to add. */ public final void add(int index, List<ItemType> toAdd) { for (ItemType aToAdd : toAdd) { add(index, assignId(aToAdd)); index++; } } /** * Adds a single item to the adapter and optionally notifies the attached ListView. */ public void add(ItemType toAdd, boolean updateList) { isChanged = true; this.mItems.add(assignId(toAdd)); if (updateList) notifyDataSetChanged(); } /** * Adds a single item to the adapter and notifies the attached ListView. */ public final void add(ItemType toAdd) { this.add(toAdd, true); } /** * Adds an array of items to the adapter and notifies the attached ListView. */ public final void add(ItemType[] toAdd) { add(new ArrayList<ItemType>(Arrays.asList(toAdd))); } /** * Adds a list of items to the adapter and notifies the attached Listview. */ public final void add(List<ItemType> toAdd) { isChanged = true; for (ItemType item : toAdd) add(item); } /** * Updates a single item in the adapter using equalTo() from SilkComparable. Once the filter finds the item, the loop is broken * so you cannot update multiple items with a single call. * <p/> * If the item is not found, it will be added to the adapter. * * @return True if the item was updated. */ public final boolean update(ItemType toUpdate) { return update(toUpdate, true); } /** * Updates a single item in the adapter using equalTo() from SilkComparable. Once the filter finds the item, the loop is broken * so you cannot update multiple items with a single call. * * @param addIfNotFound Whether or not the item will be added if it's not found. * @return True if the item was updated or added. */ public boolean update(ItemType toUpdate, boolean addIfNotFound) { boolean found = false; for (int i = 0; i < getCount(); i++) { ItemType item = getItem(i); if (toUpdate.getSilkId() == item.getSilkId()) { getItems().set(i, toUpdate); found = true; break; } } if (found) { notifyDataSetChanged(); return true; } else if (addIfNotFound) { add(toUpdate); return true; } return false; } /** * Sets the items in the adapter (clears any previous ones before adding) and notifies the attached ListView. * * @param comparator An optional comparator to sort the list with before setting it to the adapter. */ public final void set(ItemType[] toSet, Comparator<ItemType> comparator) { if (toSet == null) clear(); else set(new ArrayList<ItemType>(Arrays.asList(toSet)), comparator); } /** * Sets the items in the adapter (clears any previous ones before adding) and notifies the attached ListView. * * @param comparator An optional comparator to sort the list with before setting it to the adapter. */ public final void set(List<ItemType> toSet, Comparator<ItemType> comparator) { isChanged = true; this.mItems.clear(); if (toSet != null) { if (comparator != null) Collections.sort(toSet, comparator); for (ItemType item : toSet) add(item, false); } notifyDataSetChanged(); } /** * Checks whether or not the adapter contains an item based on the adapter's inherited Filter. */ public final boolean contains(ItemType item) { for (int i = 0; i < getCount(); i++) { ItemType curItem = getItem(i); if (item.getSilkId() == curItem.getSilkId()) return true; } return false; } /** * Removes an item from the list by its index. */ public void remove(int index) { isChanged = true; this.mItems.remove(index); notifyDataSetChanged(); } /** * Removes a single item in the adapter using equalTo() from SilkComparable. Once the filter finds the item, the loop is broken * so you cannot remove multiple items with a single call. */ public final void remove(ItemType toRemove) { for (int i = 0; i < getCount(); i++) { ItemType item = getItem(i); if (toRemove.getSilkId() == item.getSilkId()) { this.remove(i); break; } } } /** * Removes an array of items from the adapter, uses equalTo() from SilkComparable to find the items. */ public final void remove(ItemType[] toRemove) { for (ItemType item : toRemove) remove(item); } /** * Clears all items from the adapter and notifies the attached ListView. */ public void clear() { isChanged = true; this.mItems.clear(); notifyDataSetChanged(); } /** * Gets a list of all items in the adapter. */ public final List<ItemType> getItems() { return mItems; } @Override public int getCount() { return mItems.size(); } @Override public ItemType getItem(int i) { return mItems.get(i); } @Override public long getItemId(int position) { ItemType item = getItem(position); if (item == null) return position; Object id = getItemId(item); if (id instanceof Long) return (Long) id; else if (id instanceof Integer) return (Integer) id; return position; } public abstract Object getItemId(ItemType item); /** * @deprecated Override {@link #onViewCreated(int, android.view.View, com.afollestad.silk.SilkComparable)} instead. */ @Override public View getView(int i, View view, ViewGroup viewGroup) { if (view == null) { int type = getItemViewType(i); view = LayoutInflater.from(context).inflate(getLayout(i, type), null); } return onViewCreated(i, view, getItem(i)); } /** * Resets the changed state of the adapter, indicating that the adapter has not been changed. Every call * to a mutator method (e.g. add, set, remove, clear) will set it back to true. */ public void resetChanged() { isChanged = false; } /** * Marks the adapter as changed. */ public void markChanged() { isChanged = true; } /** * Gets whether or not the adapter has been changed since the last time {#resetChanged} was called. */ public final boolean isChanged() { return isChanged; } /** * Gets the scroll state set by a {@link com.afollestad.silk.views.list.SilkListView}. */ @Override public final int getScrollState() { return mScrollState; } /** * Used by the {@link com.afollestad.silk.views.list.SilkListView} to update the adapter with its scroll state. */ @Override public final void setScrollState(int state) { mScrollState = state; } }