package com.geo.smallcredit.adapter; import java.util.LinkedList; import java.util.List; import com.geo.smallcredit.listviewgroup.interfaces.ItemHeaderClickedListener; import com.geo.smallcredit.listviewgroup.view.WrapperView; import android.content.Context; import android.database.DataSetObserver; import android.graphics.drawable.Drawable; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ListAdapter; /** * A {@link ListAdapter} which wraps a {@link StickyListHeadersAdapter} and automatically handles wrapping the * result of {@link StickyListHeadersAdapter#getView(int, android.view.View, android.view.ViewGroup)} and * {@link StickyListHeadersAdapter#getHeaderView(int, android.view.View, android.view.ViewGroup)} * appropriately. * * @author Jake Wharton (jakewharton@gmail.com) */ public class AdapterWrapper extends BaseAdapter implements StickyListHeadersAdapter { public final StickyListHeadersAdapter mAdapterListHeader; private final List<View> mHeaderCache = new LinkedList<View>(); private final Context mContext; private Drawable mDivider; private int mDividerHeight; private ItemHeaderClickedListener mOnHeaderClickListener; private DataSetObserver mDataSetObserver = new DataSetObserver() { @Override public void onInvalidated() { mHeaderCache.clear(); AdapterWrapper.super.notifyDataSetInvalidated(); } @Override public void onChanged() { AdapterWrapper.super.notifyDataSetChanged(); } }; public AdapterWrapper(Context context, StickyListHeadersAdapter delegate) { this.mContext = context; this.mAdapterListHeader = delegate; delegate.registerDataSetObserver(mDataSetObserver); } public void setDivider(Drawable divider) { this.mDivider = divider; } public void setDividerHeight(int dividerHeight) { this.mDividerHeight = dividerHeight; } @Override public boolean areAllItemsEnabled() { return mAdapterListHeader.areAllItemsEnabled(); } @Override public boolean isEnabled(int position) { return mAdapterListHeader.isEnabled(position); } @Override public int getCount() { return mAdapterListHeader.getCount(); } @Override public Object getItem(int position) { return mAdapterListHeader.getItem(position); } @Override public long getItemId(int position) { return mAdapterListHeader.getItemId(position); } @Override public boolean hasStableIds() { return mAdapterListHeader.hasStableIds(); } @Override public int getItemViewType(int position) { return mAdapterListHeader.getItemViewType(position); } @Override public int getViewTypeCount() { return mAdapterListHeader.getViewTypeCount(); } @Override public boolean isEmpty() { return mAdapterListHeader.isEmpty(); } /** * Will recycle header from {@link WrapperView} if it exists */ private void recycleHeaderIfExists(WrapperView wv) { View header = wv.mHeader; if (header != null) { mHeaderCache.add(header); } } /** * Get a header view. This optionally pulls a header from the supplied {@link WrapperView} and will also * recycle the divider if it exists. */ private View configureHeader(WrapperView wv, final int position) { View header = wv.mHeader == null ? popHeader() : wv.mHeader; header = mAdapterListHeader.getHeaderView(position, header, wv); if (header == null) { throw new NullPointerException("Header view must not be null."); } // if the header isn't clickable, the listselector will be drawn on top of the header header.setClickable(true); header.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { if (mOnHeaderClickListener != null) { long headerId = mAdapterListHeader.getHeaderId(position); mOnHeaderClickListener.onItemHeaderClick(v, position, headerId); } } }); return header; } private View popHeader() { if (mHeaderCache.size() > 0) { return mHeaderCache.remove(0); } return null; } /** Returns {@code true} if the previous position has the same header ID. */ private boolean previousPositionHasSameHeader(int position) { return position != 0 && mAdapterListHeader.getHeaderId(position) == mAdapterListHeader.getHeaderId(position - 1); } @Override public WrapperView getView(int position, View convertView, ViewGroup parent) { WrapperView wv = (convertView == null) ? new WrapperView(mContext) : (WrapperView) convertView; View item = mAdapterListHeader.getView(position, wv.mItem, wv); View header = null; if (previousPositionHasSameHeader(position)) { recycleHeaderIfExists(wv); } else { header = configureHeader(wv, position); } // if ((item instanceof Checkable) && !(wv instanceof CheckableWrapperView)) { // // Need to create Checkable subclass of WrapperView for ListView to work correctly // wv = new CheckableWrapperView(mContext); // } else if (!(item instanceof Checkable) && (wv instanceof CheckableWrapperView)) { // wv = new WrapperView(mContext); // } wv.update(item, header, mDivider, mDividerHeight); return wv; } public void setOnHeaderClickListener(ItemHeaderClickedListener onHeaderClickListener) { this.mOnHeaderClickListener = onHeaderClickListener; } @Override public boolean equals(Object o) { return mAdapterListHeader.equals(o); } @Override public View getDropDownView(int position, View convertView, ViewGroup parent) { return ((BaseAdapter) mAdapterListHeader).getDropDownView(position, convertView, parent); } @Override public int hashCode() { return mAdapterListHeader.hashCode(); } @Override public void notifyDataSetChanged() { ((BaseAdapter) mAdapterListHeader).notifyDataSetChanged(); } @Override public void notifyDataSetInvalidated() { ((BaseAdapter) mAdapterListHeader).notifyDataSetInvalidated(); } @Override public String toString() { return mAdapterListHeader.toString(); } @Override public View getHeaderView(int position, View convertView, ViewGroup parent) { return mAdapterListHeader.getHeaderView(position, convertView, parent); } @Override public long getHeaderId(int position) { return mAdapterListHeader.getHeaderId(position); } }