diff options
author | Dominik Schürmann <dominik@dominikschuermann.de> | 2014-04-16 21:49:29 +0200 |
---|---|---|
committer | Dominik Schürmann <dominik@dominikschuermann.de> | 2014-04-16 21:49:29 +0200 |
commit | f7c243564f87d60df322ea9f62c1591920f8d32b (patch) | |
tree | 39d8554ccb83722843ced80297ec3e09aece00dd /libraries/StickyListHeaders/library/src | |
parent | b0c65729a98dfbd61063491a5facff2f782f56af (diff) | |
download | open-keychain-f7c243564f87d60df322ea9f62c1591920f8d32b.tar.gz open-keychain-f7c243564f87d60df322ea9f62c1591920f8d32b.tar.bz2 open-keychain-f7c243564f87d60df322ea9f62c1591920f8d32b.zip |
Use git submodules for libs, fix compilation, remove library sourcecode
Diffstat (limited to 'libraries/StickyListHeaders/library/src')
8 files changed, 0 insertions, 1587 deletions
diff --git a/libraries/StickyListHeaders/library/src/se/emilsjolander/stickylistheaders/AdapterWrapper.java b/libraries/StickyListHeaders/library/src/se/emilsjolander/stickylistheaders/AdapterWrapper.java deleted file mode 100644 index e67de0dbf..000000000 --- a/libraries/StickyListHeaders/library/src/se/emilsjolander/stickylistheaders/AdapterWrapper.java +++ /dev/null @@ -1,225 +0,0 @@ -package se.emilsjolander.stickylistheaders; - -import java.util.LinkedList; -import java.util.List; - -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.Checkable; -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) - */ -class AdapterWrapper extends BaseAdapter implements StickyListHeadersAdapter { - - interface OnHeaderClickListener { - public void onHeaderClick(View header, int itemPosition, long headerId); - } - - final StickyListHeadersAdapter mDelegate; - private final List<View> mHeaderCache = new LinkedList<View>(); - private final Context mContext; - private Drawable mDivider; - private int mDividerHeight; - private OnHeaderClickListener mOnHeaderClickListener; - private DataSetObserver mDataSetObserver = new DataSetObserver() { - - @Override - public void onInvalidated() { - mHeaderCache.clear(); - AdapterWrapper.super.notifyDataSetInvalidated(); - } - - @Override - public void onChanged() { - AdapterWrapper.super.notifyDataSetChanged(); - } - }; - - AdapterWrapper(Context context, - StickyListHeadersAdapter delegate) { - this.mContext = context; - this.mDelegate = delegate; - delegate.registerDataSetObserver(mDataSetObserver); - } - - void setDivider(Drawable divider, int dividerHeight) { - this.mDivider = divider; - this.mDividerHeight = dividerHeight; - notifyDataSetChanged(); - } - - @Override - public boolean areAllItemsEnabled() { - return mDelegate.areAllItemsEnabled(); - } - - @Override - public boolean isEnabled(int position) { - return mDelegate.isEnabled(position); - } - - @Override - public int getCount() { - return mDelegate.getCount(); - } - - @Override - public Object getItem(int position) { - return mDelegate.getItem(position); - } - - @Override - public long getItemId(int position) { - return mDelegate.getItemId(position); - } - - @Override - public boolean hasStableIds() { - return mDelegate.hasStableIds(); - } - - @Override - public int getItemViewType(int position) { - return mDelegate.getItemViewType(position); - } - - @Override - public int getViewTypeCount() { - return mDelegate.getViewTypeCount(); - } - - @Override - public boolean isEmpty() { - return mDelegate.isEmpty(); - } - - /** - * Will recycle header from {@link WrapperView} if it exists - */ - private void recycleHeaderIfExists(WrapperView wv) { - View header = wv.mHeader; - if (header != null) { - // reset the headers visibility when adding it to the cache - header.setVisibility(View.VISIBLE); - 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 = mDelegate.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 = mDelegate.getHeaderId(position); - mOnHeaderClickListener.onHeaderClick(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 - && mDelegate.getHeaderId(position) == mDelegate - .getHeaderId(position - 1); - } - - @Override - public WrapperView getView(int position, View convertView, ViewGroup parent) { - WrapperView wv = (convertView == null) ? new WrapperView(mContext) : (WrapperView) convertView; - View item = mDelegate.getView(position, wv.mItem, parent); - 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(OnHeaderClickListener onHeaderClickListener){ - this.mOnHeaderClickListener = onHeaderClickListener; - } - - @Override - public boolean equals(Object o) { - return mDelegate.equals(o); - } - - @Override - public View getDropDownView(int position, View convertView, ViewGroup parent) { - return ((BaseAdapter) mDelegate).getDropDownView(position, convertView, parent); - } - - @Override - public int hashCode() { - return mDelegate.hashCode(); - } - - @Override - public void notifyDataSetChanged() { - ((BaseAdapter) mDelegate).notifyDataSetChanged(); - } - - @Override - public void notifyDataSetInvalidated() { - ((BaseAdapter) mDelegate).notifyDataSetInvalidated(); - } - - @Override - public String toString() { - return mDelegate.toString(); - } - - @Override - public View getHeaderView(int position, View convertView, ViewGroup parent) { - return mDelegate.getHeaderView(position, convertView, parent); - } - - @Override - public long getHeaderId(int position) { - return mDelegate.getHeaderId(position); - } - -} diff --git a/libraries/StickyListHeaders/library/src/se/emilsjolander/stickylistheaders/ApiLevelTooLowException.java b/libraries/StickyListHeaders/library/src/se/emilsjolander/stickylistheaders/ApiLevelTooLowException.java deleted file mode 100644 index 5b0a83827..000000000 --- a/libraries/StickyListHeaders/library/src/se/emilsjolander/stickylistheaders/ApiLevelTooLowException.java +++ /dev/null @@ -1,11 +0,0 @@ -package se.emilsjolander.stickylistheaders; - -public class ApiLevelTooLowException extends RuntimeException { - - private static final long serialVersionUID = -5480068364264456757L; - - public ApiLevelTooLowException(int versionCode) { - super("Requires API level " + versionCode); - } - -} diff --git a/libraries/StickyListHeaders/library/src/se/emilsjolander/stickylistheaders/CheckableWrapperView.java b/libraries/StickyListHeaders/library/src/se/emilsjolander/stickylistheaders/CheckableWrapperView.java deleted file mode 100644 index 9039c3f5c..000000000 --- a/libraries/StickyListHeaders/library/src/se/emilsjolander/stickylistheaders/CheckableWrapperView.java +++ /dev/null @@ -1,31 +0,0 @@ -package se.emilsjolander.stickylistheaders; - -import android.content.Context; -import android.widget.Checkable; - -/** - * A WrapperView that implements the checkable interface - * - * @author Emil Sjölander - */ -class CheckableWrapperView extends WrapperView implements Checkable { - - public CheckableWrapperView(final Context context) { - super(context); - } - - @Override - public boolean isChecked() { - return ((Checkable) mItem).isChecked(); - } - - @Override - public void setChecked(final boolean checked) { - ((Checkable) mItem).setChecked(checked); - } - - @Override - public void toggle() { - setChecked(!isChecked()); - } -} diff --git a/libraries/StickyListHeaders/library/src/se/emilsjolander/stickylistheaders/SectionIndexerAdapterWrapper.java b/libraries/StickyListHeaders/library/src/se/emilsjolander/stickylistheaders/SectionIndexerAdapterWrapper.java deleted file mode 100644 index ff7e293af..000000000 --- a/libraries/StickyListHeaders/library/src/se/emilsjolander/stickylistheaders/SectionIndexerAdapterWrapper.java +++ /dev/null @@ -1,32 +0,0 @@ -package se.emilsjolander.stickylistheaders; - -import android.content.Context; -import android.widget.SectionIndexer; - -class SectionIndexerAdapterWrapper extends - AdapterWrapper implements SectionIndexer { - - final SectionIndexer mSectionIndexerDelegate; - - SectionIndexerAdapterWrapper(Context context, - StickyListHeadersAdapter delegate) { - super(context, delegate); - mSectionIndexerDelegate = (SectionIndexer) delegate; - } - - @Override - public int getPositionForSection(int section) { - return mSectionIndexerDelegate.getPositionForSection(section); - } - - @Override - public int getSectionForPosition(int position) { - return mSectionIndexerDelegate.getSectionForPosition(position); - } - - @Override - public Object[] getSections() { - return mSectionIndexerDelegate.getSections(); - } - -} diff --git a/libraries/StickyListHeaders/library/src/se/emilsjolander/stickylistheaders/StickyListHeadersAdapter.java b/libraries/StickyListHeaders/library/src/se/emilsjolander/stickylistheaders/StickyListHeadersAdapter.java deleted file mode 100644 index 8b80b71f1..000000000 --- a/libraries/StickyListHeaders/library/src/se/emilsjolander/stickylistheaders/StickyListHeadersAdapter.java +++ /dev/null @@ -1,38 +0,0 @@ -package se.emilsjolander.stickylistheaders; - -import android.view.View; -import android.view.ViewGroup; -import android.widget.ListAdapter; - -public interface StickyListHeadersAdapter extends ListAdapter { - /** - * Get a View that displays the header data at the specified position in the - * set. You can either create a View manually or inflate it from an XML layout - * file. - * - * @param position - * The position of the item within the adapter's data set of the item whose - * header view we want. - * @param convertView - * The old view to reuse, if possible. Note: You should check that this view is - * non-null and of an appropriate type before using. If it is not possible to - * convert this view to display the correct data, this method can create a new - * view. - * @param parent - * The parent that this view will eventually be attached to. - * @return - * A View corresponding to the data at the specified position. - */ - View getHeaderView(int position, View convertView, ViewGroup parent); - - /** - * Get the header id associated with the specified position in the list. - * - * @param position - * The position of the item within the adapter's data set whose header id we - * want. - * @return - * The id of the header at the specified position. - */ - long getHeaderId(int position); -} diff --git a/libraries/StickyListHeaders/library/src/se/emilsjolander/stickylistheaders/StickyListHeadersListView.java b/libraries/StickyListHeaders/library/src/se/emilsjolander/stickylistheaders/StickyListHeadersListView.java deleted file mode 100644 index 476f6cfad..000000000 --- a/libraries/StickyListHeaders/library/src/se/emilsjolander/stickylistheaders/StickyListHeadersListView.java +++ /dev/null @@ -1,925 +0,0 @@ -package se.emilsjolander.stickylistheaders; - -import android.annotation.SuppressLint; -import android.annotation.TargetApi; -import android.content.Context; -import android.content.res.TypedArray; -import android.database.DataSetObserver; -import android.graphics.Canvas; -import android.graphics.drawable.Drawable; -import android.os.Build; -import android.util.AttributeSet; -import android.util.Log; -import android.util.SparseBooleanArray; -import android.view.View; -import android.view.ViewGroup; -import android.widget.AbsListView; -import android.widget.AbsListView.OnScrollListener; -import android.widget.AdapterView.OnItemClickListener; -import android.widget.AdapterView.OnItemLongClickListener; -import android.widget.FrameLayout; -import android.widget.ListView; -import android.widget.SectionIndexer; - -import se.emilsjolander.stickylistheaders.WrapperViewList.LifeCycleListener; - -/** - * Even though this is a FrameLayout subclass we it is called a ListView. This - * is because of 2 reasons. 1. It acts like as ListView 2. It used to be a - * ListView subclass and i did not was to change to name causing compatibility - * errors. - * - * @author Emil Sjölander - */ -public class StickyListHeadersListView extends FrameLayout { - - public interface OnHeaderClickListener { - public void onHeaderClick(StickyListHeadersListView l, View header, - int itemPosition, long headerId, boolean currentlySticky); - } - - /** - * Notifies the listener when the sticky headers top offset has changed. - */ - public interface OnStickyHeaderOffsetChangedListener { - /** - * @param l The view parent - * @param header The currently sticky header being offset. - * This header is not guaranteed to have it's measurements set. - * It is however guaranteed that this view has been measured, - * therefor you should user getMeasured* methods instead of - * get* methods for determining the view's size. - * @param offset The amount the sticky header is offset by towards to top of the screen. - */ - public void onStickyHeaderOffsetChanged(StickyListHeadersListView l, View header, int offset); - } - - /* --- Children --- */ - private WrapperViewList mList; - private View mHeader; - - /* --- Header state --- */ - private Long mHeaderId; - // used to not have to call getHeaderId() all the time - private Integer mHeaderPosition; - private Integer mHeaderOffset; - - /* --- Delegates --- */ - private OnScrollListener mOnScrollListenerDelegate; - private AdapterWrapper mAdapter; - - /* --- Settings --- */ - private boolean mAreHeadersSticky = true; - private boolean mClippingToPadding = true; - private boolean mIsDrawingListUnderStickyHeader = true; - private int mPaddingLeft = 0; - private int mPaddingTop = 0; - private int mPaddingRight = 0; - private int mPaddingBottom = 0; - - /* --- Other --- */ - private OnHeaderClickListener mOnHeaderClickListener; - private OnStickyHeaderOffsetChangedListener mOnStickyHeaderOffsetChangedListener; - private AdapterWrapperDataSetObserver mDataSetObserver; - private Drawable mDivider; - private int mDividerHeight; - - public StickyListHeadersListView(Context context) { - this(context, null); - } - - public StickyListHeadersListView(Context context, AttributeSet attrs) { - this(context, attrs, 0); - } - - @TargetApi(Build.VERSION_CODES.HONEYCOMB) - public StickyListHeadersListView(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - - // Initialize the wrapped list - mList = new WrapperViewList(context); - - // null out divider, dividers are handled by adapter so they look good with headers - mDivider = mList.getDivider(); - mDividerHeight = mList.getDividerHeight(); - mList.setDivider(null); - mList.setDividerHeight(0); - - mList.setVerticalScrollBarEnabled(isVerticalScrollBarEnabled()); - mList.setHorizontalScrollBarEnabled(isHorizontalScrollBarEnabled()); - - if (attrs != null) { - TypedArray a = context.getTheme().obtainStyledAttributes(attrs,R.styleable.StickyListHeadersListView, 0, 0); - - try { - // -- View attributes -- - int padding = a.getDimensionPixelSize(R.styleable.StickyListHeadersListView_android_padding, 0); - mPaddingLeft = a.getDimensionPixelSize(R.styleable.StickyListHeadersListView_android_paddingLeft, padding); - mPaddingTop = a.getDimensionPixelSize(R.styleable.StickyListHeadersListView_android_paddingTop, padding); - mPaddingRight = a.getDimensionPixelSize(R.styleable.StickyListHeadersListView_android_paddingRight, padding); - mPaddingBottom = a.getDimensionPixelSize(R.styleable.StickyListHeadersListView_android_paddingBottom, padding); - - setPadding(mPaddingLeft, mPaddingTop, mPaddingRight, - mPaddingBottom); - - // Set clip to padding on the list and reset value to default on - // wrapper - mClippingToPadding = a.getBoolean(R.styleable.StickyListHeadersListView_android_clipToPadding, true); - super.setClipToPadding(true); - mList.setClipToPadding(mClippingToPadding); - - // -- ListView attributes -- - mList.setFadingEdgeLength(a.getDimensionPixelSize(R.styleable.StickyListHeadersListView_android_fadingEdgeLength, - mList.getVerticalFadingEdgeLength())); - final int fadingEdge = a.getInt(R.styleable.StickyListHeadersListView_android_requiresFadingEdge, 0); - if (fadingEdge == 0x00001000) { - mList.setVerticalFadingEdgeEnabled(false); - mList.setHorizontalFadingEdgeEnabled(true); - } else if (fadingEdge == 0x00002000) { - mList.setVerticalFadingEdgeEnabled(true); - mList.setHorizontalFadingEdgeEnabled(false); - } else { - mList.setVerticalFadingEdgeEnabled(false); - mList.setHorizontalFadingEdgeEnabled(false); - } - mList.setCacheColorHint(a - .getColor(R.styleable.StickyListHeadersListView_android_cacheColorHint, mList.getCacheColorHint())); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { - mList.setChoiceMode(a.getInt(R.styleable.StickyListHeadersListView_android_choiceMode, - mList.getChoiceMode())); - } - mList.setDrawSelectorOnTop(a.getBoolean(R.styleable.StickyListHeadersListView_android_drawSelectorOnTop, false)); - mList.setFastScrollEnabled(a.getBoolean(R.styleable.StickyListHeadersListView_android_fastScrollEnabled, - mList.isFastScrollEnabled())); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { - mList.setFastScrollAlwaysVisible(a.getBoolean( - R.styleable.StickyListHeadersListView_android_fastScrollAlwaysVisible, - mList.isFastScrollAlwaysVisible())); - } - - mList.setScrollBarStyle(a.getInt(R.styleable.StickyListHeadersListView_android_scrollbarStyle, 0)); - - if (a.hasValue(R.styleable.StickyListHeadersListView_android_listSelector)) { - mList.setSelector(a.getDrawable(R.styleable.StickyListHeadersListView_android_listSelector)); - } - - mList.setScrollingCacheEnabled(a.getBoolean(R.styleable.StickyListHeadersListView_android_scrollingCache, - mList.isScrollingCacheEnabled())); - - if (a.hasValue(R.styleable.StickyListHeadersListView_android_divider)) { - mDivider = a.getDrawable(R.styleable.StickyListHeadersListView_android_divider); - } - - mDividerHeight = a.getDimensionPixelSize(R.styleable.StickyListHeadersListView_android_dividerHeight, - mDividerHeight); - - // -- StickyListHeaders attributes -- - mAreHeadersSticky = a.getBoolean(R.styleable.StickyListHeadersListView_hasStickyHeaders, true); - mIsDrawingListUnderStickyHeader = a.getBoolean( - R.styleable.StickyListHeadersListView_isDrawingListUnderStickyHeader, - true); - } finally { - a.recycle(); - } - } - - // attach some listeners to the wrapped list - mList.setLifeCycleListener(new WrapperViewListLifeCycleListener()); - mList.setOnScrollListener(new WrapperListScrollListener()); - - addView(mList); - } - - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - super.onMeasure(widthMeasureSpec, heightMeasureSpec); - measureHeader(mHeader); - } - - private void ensureHeaderHasCorrectLayoutParams(View header) { - ViewGroup.LayoutParams lp = header.getLayoutParams(); - if (lp == null) { - lp = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT); - } else if (lp.height == LayoutParams.MATCH_PARENT) { - lp.height = LayoutParams.WRAP_CONTENT; - } - header.setLayoutParams(lp); - } - - private void measureHeader(View header) { - if (header != null) { - final int width = getMeasuredWidth() - mPaddingLeft - mPaddingRight; - final int parentWidthMeasureSpec = MeasureSpec.makeMeasureSpec( - width, MeasureSpec.EXACTLY); - final int parentHeightMeasureSpec = MeasureSpec.makeMeasureSpec(0, - MeasureSpec.UNSPECIFIED); - measureChild(header, parentWidthMeasureSpec, - parentHeightMeasureSpec); - } - } - - @Override - protected void onLayout(boolean changed, int left, int top, int right, - int bottom) { - mList.layout(0, 0, mList.getMeasuredWidth(), getHeight()); - if (mHeader != null) { - MarginLayoutParams lp = (MarginLayoutParams) mHeader - .getLayoutParams(); - int headerTop = lp.topMargin - + (mClippingToPadding ? mPaddingTop : 0); - // The left parameter must for some reason be set to 0. - // I think it should be set to mPaddingLeft but apparently not - mHeader.layout(mPaddingLeft, headerTop, mHeader.getMeasuredWidth() - + mPaddingLeft, headerTop + mHeader.getMeasuredHeight()); - } - } - - @Override - protected void dispatchDraw(Canvas canvas) { - // Only draw the list here. - // The header should be drawn right after the lists children are drawn. - // This is done so that the header is above the list items - // but below the list decorators (scroll bars etc). - drawChild(canvas, mList, 0); - } - - // Reset values tied the header. also remove header form layout - // This is called in response to the data set or the adapter changing - private void clearHeader() { - if (mHeader != null) { - removeView(mHeader); - mHeader = null; - mHeaderId = null; - mHeaderPosition = null; - mHeaderOffset = null; - - // reset the top clipping length - mList.setTopClippingLength(0); - updateHeaderVisibilities(); - } - } - - private void updateOrClearHeader(int firstVisiblePosition) { - final int adapterCount = mAdapter == null ? 0 : mAdapter.getCount(); - if (adapterCount == 0 || !mAreHeadersSticky) { - return; - } - - final int headerViewCount = mList.getHeaderViewsCount(); - final int realFirstVisibleItem = firstVisiblePosition - headerViewCount; - - // It is not a mistake to call getFirstVisiblePosition() here. - // Most of the time getFixedFirstVisibleItem() should be called - // but that does not work great together with getChildAt() - final boolean doesListHaveChildren = mList.getChildCount() != 0; - final boolean isFirstViewBelowTop = doesListHaveChildren && mList - .getFirstVisiblePosition() == 0 - && mList.getChildAt(0).getTop() > (mClippingToPadding ? mPaddingTop : 0); - final boolean isFirstVisibleItemOutsideAdapterRange = realFirstVisibleItem > adapterCount - 1 - || realFirstVisibleItem < 0; - if (!doesListHaveChildren || isFirstVisibleItemOutsideAdapterRange - || isFirstViewBelowTop) { - clearHeader(); - return; - } - - updateHeader(realFirstVisibleItem); - } - - private void updateHeader(int firstVisiblePosition) { - - // check if there is a new header should be sticky - if (mHeaderPosition == null || mHeaderPosition != firstVisiblePosition) { - mHeaderPosition = firstVisiblePosition; - final long headerId = mAdapter.getHeaderId(firstVisiblePosition); - if (mHeaderId == null || mHeaderId != headerId) { - mHeaderId = headerId; - final View header = mAdapter.getHeaderView(mHeaderPosition, - mHeader, this); - if (mHeader != header) { - if (header == null) { - throw new NullPointerException("header may not be null"); - } - swapHeader(header); - } - - ensureHeaderHasCorrectLayoutParams(mHeader); - measureHeader(mHeader); - - // Reset mHeaderOffset to null ensuring - // that it will be set on the header and - // not skipped for performance reasons. - mHeaderOffset = null; - } - } - - int headerOffset = 0; - - // Calculate new header offset - // Skip looking at the first view. it never matters because it always - // results in a headerOffset = 0 - int headerBottom = mHeader.getMeasuredHeight() - + (mClippingToPadding ? mPaddingTop : 0); - for (int i = 0; i < mList.getChildCount(); i++) { - final View child = mList.getChildAt(i); - final boolean doesChildHaveHeader = child instanceof WrapperView - && ((WrapperView) child).hasHeader(); - final boolean isChildFooter = mList.containsFooterView(child); - if (child.getTop() >= (mClippingToPadding ? mPaddingTop : 0) - && (doesChildHaveHeader || isChildFooter)) { - headerOffset = Math.min(child.getTop() - headerBottom, 0); - break; - } - } - - setHeaderOffet(headerOffset); - - if (!mIsDrawingListUnderStickyHeader) { - mList.setTopClippingLength(mHeader.getMeasuredHeight() - + mHeaderOffset); - } - - updateHeaderVisibilities(); - } - - private void swapHeader(View newHeader) { - if (mHeader != null) { - removeView(mHeader); - } - mHeader = newHeader; - addView(mHeader); - mHeader.setOnClickListener(new OnClickListener() { - - @Override - public void onClick(View v) { - if (mOnHeaderClickListener != null) { - mOnHeaderClickListener.onHeaderClick( - StickyListHeadersListView.this, mHeader, - mHeaderPosition, mHeaderId, true); - } - } - - }); - } - - // hides the headers in the list under the sticky header. - // Makes sure the other ones are showing - private void updateHeaderVisibilities() { - int top; - if (mHeader != null) { - top = mHeader.getMeasuredHeight() - + (mHeaderOffset != null ? mHeaderOffset : 0); - } else { - top = mClippingToPadding ? mPaddingTop : 0; - } - int childCount = mList.getChildCount(); - for (int i = 0; i < childCount; i++) { - - // ensure child is a wrapper view - View child = mList.getChildAt(i); - if (!(child instanceof WrapperView)) { - continue; - } - - // ensure wrapper view child has a header - WrapperView wrapperViewChild = (WrapperView) child; - if (!wrapperViewChild.hasHeader()) { - continue; - } - - // update header views visibility - View childHeader = wrapperViewChild.mHeader; - if (wrapperViewChild.getTop() < top) { - if (childHeader.getVisibility() != View.INVISIBLE) { - childHeader.setVisibility(View.INVISIBLE); - } - } else { - if (childHeader.getVisibility() != View.VISIBLE) { - childHeader.setVisibility(View.VISIBLE); - } - } - } - } - - // Wrapper around setting the header offset in different ways depending on - // the API version - @SuppressLint("NewApi") - private void setHeaderOffet(int offset) { - if (mHeaderOffset == null || mHeaderOffset != offset) { - mHeaderOffset = offset; - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { - mHeader.setTranslationY(mHeaderOffset); - } else { - MarginLayoutParams params = (MarginLayoutParams) mHeader - .getLayoutParams(); - params.topMargin = mHeaderOffset; - mHeader.setLayoutParams(params); - } - if (mOnStickyHeaderOffsetChangedListener != null) { - mOnStickyHeaderOffsetChangedListener - .onStickyHeaderOffsetChanged(this, mHeader, -mHeaderOffset); - } - } - } - - private class AdapterWrapperDataSetObserver extends DataSetObserver { - - @Override - public void onChanged() { - clearHeader(); - } - - @Override - public void onInvalidated() { - clearHeader(); - } - - } - - private class WrapperListScrollListener implements OnScrollListener { - - @Override - public void onScroll(AbsListView view, int firstVisibleItem, - int visibleItemCount, int totalItemCount) { - if (mOnScrollListenerDelegate != null) { - mOnScrollListenerDelegate.onScroll(view, firstVisibleItem, - visibleItemCount, totalItemCount); - } - updateOrClearHeader(mList.getFixedFirstVisibleItem()); - } - - @Override - public void onScrollStateChanged(AbsListView view, int scrollState) { - if (mOnScrollListenerDelegate != null) { - mOnScrollListenerDelegate.onScrollStateChanged(view, - scrollState); - } - } - - } - - private class WrapperViewListLifeCycleListener implements LifeCycleListener { - - @Override - public void onDispatchDrawOccurred(Canvas canvas) { - // onScroll is not called often at all before froyo - // therefor we need to update the header here as well. - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.FROYO) { - updateOrClearHeader(mList.getFixedFirstVisibleItem()); - } - if (mHeader != null) { - if (mClippingToPadding) { - canvas.save(); - canvas.clipRect(0, mPaddingTop, getRight(), getBottom()); - drawChild(canvas, mHeader, 0); - canvas.restore(); - } else { - drawChild(canvas, mHeader, 0); - } - } - } - - } - - private class AdapterWrapperHeaderClickHandler implements - AdapterWrapper.OnHeaderClickListener { - - @Override - public void onHeaderClick(View header, int itemPosition, long headerId) { - mOnHeaderClickListener.onHeaderClick( - StickyListHeadersListView.this, header, itemPosition, - headerId, false); - } - - } - - private boolean isStartOfSection(int position) { - return position == 0 - || mAdapter.getHeaderId(position) != mAdapter - .getHeaderId(position - 1); - } - - private int getHeaderOverlap(int position) { - boolean isStartOfSection = isStartOfSection(position); - if (!isStartOfSection) { - View header = mAdapter.getHeaderView(position, null, mList); - if (header == null) { - throw new NullPointerException("header may not be null"); - } - ensureHeaderHasCorrectLayoutParams(header); - measureHeader(header); - return header.getMeasuredHeight(); - } - return 0; - } - - /* ---------- StickyListHeaders specific API ---------- */ - - public void setAreHeadersSticky(boolean areHeadersSticky) { - mAreHeadersSticky = areHeadersSticky; - if (!areHeadersSticky) { - clearHeader(); - } else { - updateOrClearHeader(mList.getFixedFirstVisibleItem()); - } - // invalidating the list will trigger dispatchDraw() - mList.invalidate(); - } - - public boolean areHeadersSticky() { - return mAreHeadersSticky; - } - - /** - * Use areHeadersSticky() method instead - */ - @Deprecated - public boolean getAreHeadersSticky() { - return areHeadersSticky(); - } - - public void setDrawingListUnderStickyHeader( - boolean drawingListUnderStickyHeader) { - mIsDrawingListUnderStickyHeader = drawingListUnderStickyHeader; - // reset the top clipping length - mList.setTopClippingLength(0); - } - - public boolean isDrawingListUnderStickyHeader() { - return mIsDrawingListUnderStickyHeader; - } - - public void setOnHeaderClickListener(OnHeaderClickListener listener) { - mOnHeaderClickListener = listener; - if (mAdapter != null) { - if (mOnHeaderClickListener != null) { - mAdapter.setOnHeaderClickListener(new AdapterWrapperHeaderClickHandler()); - } else { - mAdapter.setOnHeaderClickListener(null); - } - } - } - - public void setOnStickyHeaderOffsetChangedListener(OnStickyHeaderOffsetChangedListener listener) { - mOnStickyHeaderOffsetChangedListener = listener; - } - - public View getListChildAt(int index) { - return mList.getChildAt(index); - } - - public int getListChildCount() { - return mList.getChildCount(); - } - - /** - * Use the method with extreme caution!! Changing any values on the - * underlying ListView might break everything. - * - * @return the ListView backing this view. - */ - public ListView getWrappedList() { - return mList; - } - - /* ---------- ListView delegate methods ---------- */ - - public void setAdapter(StickyListHeadersAdapter adapter) { - if (adapter == null) { - mList.setAdapter(null); - clearHeader(); - return; - } - if (mAdapter != null) { - mAdapter.unregisterDataSetObserver(mDataSetObserver); - } - - if (adapter instanceof SectionIndexer) { - mAdapter = new SectionIndexerAdapterWrapper(getContext(), adapter); - } else { - mAdapter = new AdapterWrapper(getContext(), adapter); - } - mDataSetObserver = new AdapterWrapperDataSetObserver(); - mAdapter.registerDataSetObserver(mDataSetObserver); - - if (mOnHeaderClickListener != null) { - mAdapter.setOnHeaderClickListener(new AdapterWrapperHeaderClickHandler()); - } else { - mAdapter.setOnHeaderClickListener(null); - } - - mAdapter.setDivider(mDivider, mDividerHeight); - - mList.setAdapter(mAdapter); - clearHeader(); - } - - public StickyListHeadersAdapter getAdapter() { - return mAdapter == null ? null : mAdapter.mDelegate; - } - - public void setDivider(Drawable divider) { - mDivider = divider; - if (mAdapter != null) { - mAdapter.setDivider(mDivider, mDividerHeight); - } - } - - public void setDividerHeight(int dividerHeight) { - mDividerHeight = dividerHeight; - if (mAdapter != null) { - mAdapter.setDivider(mDivider, mDividerHeight); - } - } - - public Drawable getDivider() { - return mDivider; - } - - public int getDividerHeight() { - return mDividerHeight; - } - - public void setOnScrollListener(OnScrollListener onScrollListener) { - mOnScrollListenerDelegate = onScrollListener; - } - - public void setOnItemClickListener(OnItemClickListener listener) { - mList.setOnItemClickListener(listener); - } - - public void setOnItemLongClickListener(OnItemLongClickListener listener) { - mList.setOnItemLongClickListener(listener); - } - - public void addHeaderView(View v, Object data, boolean isSelectable) { - mList.addHeaderView(v, data, isSelectable); - } - - public void addHeaderView(View v) { - mList.addHeaderView(v); - } - - public void removeHeaderView(View v) { - mList.removeHeaderView(v); - } - - public int getHeaderViewsCount() { - return mList.getHeaderViewsCount(); - } - - public void addFooterView(View v) { - mList.addFooterView(v); - } - - public void removeFooterView(View v) { - mList.removeFooterView(v); - } - - public int getFooterViewsCount() { - return mList.getFooterViewsCount(); - } - - public void setEmptyView(View v) { - mList.setEmptyView(v); - } - - public View getEmptyView() { - return mList.getEmptyView(); - } - - @Override - public void setVerticalScrollBarEnabled(boolean verticalScrollBarEnabled) { - mList.setVerticalScrollBarEnabled(verticalScrollBarEnabled); - } - - @Override - public void setHorizontalScrollBarEnabled(boolean horizontalScrollBarEnabled) { - mList.setHorizontalScrollBarEnabled(horizontalScrollBarEnabled); - } - - @TargetApi(Build.VERSION_CODES.FROYO) - public void smoothScrollBy(int distance, int duration) { - requireSdkVersion(Build.VERSION_CODES.FROYO); - mList.smoothScrollBy(distance, duration); - } - - @TargetApi(Build.VERSION_CODES.HONEYCOMB) - public void smoothScrollByOffset(int offset) { - requireSdkVersion(Build.VERSION_CODES.HONEYCOMB); - mList.smoothScrollByOffset(offset); - } - - @SuppressLint("NewApi") - @TargetApi(Build.VERSION_CODES.FROYO) - public void smoothScrollToPosition(int position) { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) { - mList.smoothScrollToPosition(position); - } else { - int offset = mAdapter == null ? 0 : getHeaderOverlap(position); - offset -= mClippingToPadding ? 0 : mPaddingTop; - mList.smoothScrollToPositionFromTop(position, offset); - } - } - - @TargetApi(Build.VERSION_CODES.FROYO) - public void smoothScrollToPosition(int position, int boundPosition) { - requireSdkVersion(Build.VERSION_CODES.FROYO); - mList.smoothScrollToPosition(position, boundPosition); - } - - @TargetApi(Build.VERSION_CODES.HONEYCOMB) - public void smoothScrollToPositionFromTop(int position, int offset) { - requireSdkVersion(Build.VERSION_CODES.HONEYCOMB); - offset += mAdapter == null ? 0 : getHeaderOverlap(position); - offset -= mClippingToPadding ? 0 : mPaddingTop; - mList.smoothScrollToPositionFromTop(position, offset); - } - - @TargetApi(Build.VERSION_CODES.HONEYCOMB) - public void smoothScrollToPositionFromTop(int position, int offset, - int duration) { - requireSdkVersion(Build.VERSION_CODES.HONEYCOMB); - offset += mAdapter == null ? 0 : getHeaderOverlap(position); - offset -= mClippingToPadding ? 0 : mPaddingTop; - mList.smoothScrollToPositionFromTop(position, offset, duration); - } - - public void setSelection(int position) { - setSelectionFromTop(position, 0); - } - - public void setSelectionAfterHeaderView() { - mList.setSelectionAfterHeaderView(); - } - - public void setSelectionFromTop(int position, int y) { - y += mAdapter == null ? 0 : getHeaderOverlap(position); - y -= mClippingToPadding ? 0 : mPaddingTop; - mList.setSelectionFromTop(position, y); - } - - public void setSelector(Drawable sel) { - mList.setSelector(sel); - } - - public void setSelector(int resID) { - mList.setSelector(resID); - } - - public int getFirstVisiblePosition() { - return mList.getFirstVisiblePosition(); - } - - public int getLastVisiblePosition() { - return mList.getLastVisiblePosition(); - } - - public void setChoiceMode(int choiceMode) { - mList.setChoiceMode(choiceMode); - } - - public void setItemChecked(int position, boolean value) { - mList.setItemChecked(position, value); - } - - @TargetApi(Build.VERSION_CODES.HONEYCOMB) - public int getCheckedItemCount() { - requireSdkVersion(Build.VERSION_CODES.HONEYCOMB); - return mList.getCheckedItemCount(); - } - - @TargetApi(Build.VERSION_CODES.FROYO) - public long[] getCheckedItemIds() { - requireSdkVersion(Build.VERSION_CODES.FROYO); - return mList.getCheckedItemIds(); - } - - public int getCheckedItemPosition() { - return mList.getCheckedItemPosition(); - } - - public SparseBooleanArray getCheckedItemPositions() { - return mList.getCheckedItemPositions(); - } - - public int getCount() { - return mList.getCount(); - } - - public Object getItemAtPosition(int position) { - return mList.getItemAtPosition(position); - } - - public long getItemIdAtPosition(int position) { - return mList.getItemIdAtPosition(position); - } - - @Override - public void setOnCreateContextMenuListener(OnCreateContextMenuListener l) { - mList.setOnCreateContextMenuListener(l); - } - - @Override - public boolean showContextMenu() { - return mList.showContextMenu(); - } - - public void invalidateViews() { - mList.invalidateViews(); - } - - @Override - public void setClipToPadding(boolean clipToPadding) { - if (mList != null) { - mList.setClipToPadding(clipToPadding); - } - mClippingToPadding = clipToPadding; - } - - @Override - public void setPadding(int left, int top, int right, int bottom) { - mPaddingLeft = left; - mPaddingTop = top; - mPaddingRight = right; - mPaddingBottom = bottom; - - if (mList != null) { - mList.setPadding(left, top, right, bottom); - } - super.setPadding(0, 0, 0, 0); - requestLayout(); - } - - /* - * Overrides an @hide method in View - */ - protected void recomputePadding() { - setPadding(mPaddingLeft, mPaddingTop, mPaddingRight, mPaddingBottom); - } - - @Override - public int getPaddingLeft() { - return mPaddingLeft; - } - - @Override - public int getPaddingTop() { - return mPaddingTop; - } - - @Override - public int getPaddingRight() { - return mPaddingRight; - } - - @Override - public int getPaddingBottom() { - return mPaddingBottom; - } - - public void setFastScrollEnabled(boolean fastScrollEnabled) { - mList.setFastScrollEnabled(fastScrollEnabled); - } - - /** - * @throws ApiLevelTooLowException on pre-Honeycomb device. - * @see android.widget.AbsListView#setFastScrollAlwaysVisible(boolean) - */ - @TargetApi(Build.VERSION_CODES.HONEYCOMB) - public void setFastScrollAlwaysVisible(boolean alwaysVisible) { - requireSdkVersion(Build.VERSION_CODES.HONEYCOMB); - mList.setFastScrollAlwaysVisible(alwaysVisible); - } - - /** - * @return true if the fast scroller will always show. False on pre-Honeycomb devices. - * @see android.widget.AbsListView#isFastScrollAlwaysVisible() - */ - @TargetApi(Build.VERSION_CODES.HONEYCOMB) - public boolean isFastScrollAlwaysVisible() { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) { - return false; - } - return mList.isFastScrollAlwaysVisible(); - } - - public void setScrollBarStyle(int style) { - mList.setScrollBarStyle(style); - } - - public int getScrollBarStyle() { - return mList.getScrollBarStyle(); - } - - private void requireSdkVersion(int versionCode) { - if (Build.VERSION.SDK_INT < versionCode) { - throw new ApiLevelTooLowException(versionCode); - } - } - - public int getPositionForView(View view) { - return mList.getPositionForView(view); - } - -} diff --git a/libraries/StickyListHeaders/library/src/se/emilsjolander/stickylistheaders/WrapperView.java b/libraries/StickyListHeaders/library/src/se/emilsjolander/stickylistheaders/WrapperView.java deleted file mode 100644 index f51416c1c..000000000 --- a/libraries/StickyListHeaders/library/src/se/emilsjolander/stickylistheaders/WrapperView.java +++ /dev/null @@ -1,150 +0,0 @@ -package se.emilsjolander.stickylistheaders; - -import android.content.Context; -import android.graphics.Canvas; -import android.graphics.drawable.Drawable; -import android.os.Build; -import android.view.View; -import android.view.ViewGroup; -import android.view.ViewParent; - -/** - * - * the view that wrapps a divider header and a normal list item. The listview sees this as 1 item - * - * @author Emil Sjölander - */ -public class WrapperView extends ViewGroup { - - View mItem; - Drawable mDivider; - int mDividerHeight; - View mHeader; - int mItemTop; - - WrapperView(Context c) { - super(c); - } - - public boolean hasHeader() { - return mHeader != null; - } - - public View getItem() { - return mItem; - } - - public View getHeader() { - return mHeader; - } - - void update(View item, View header, Drawable divider, int dividerHeight) { - - //every wrapperview must have a list item - if (item == null) { - throw new NullPointerException("List view item must not be null."); - } - - //only remove the current item if it is not the same as the new item. this can happen if wrapping a recycled view - if (this.mItem != item) { - removeView(this.mItem); - this.mItem = item; - final ViewParent parent = item.getParent(); - if(parent != null && parent != this) { - if(parent instanceof ViewGroup) { - ((ViewGroup) parent).removeView(item); - } - } - addView(item); - } - - //same logik as above but for the header - if (this.mHeader != header) { - if (this.mHeader != null) { - removeView(this.mHeader); - } - this.mHeader = header; - if (header != null) { - addView(header); - } - } - - if (this.mDivider != divider) { - this.mDivider = divider; - this.mDividerHeight = dividerHeight; - invalidate(); - } - } - - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - int measuredWidth = MeasureSpec.getSize(widthMeasureSpec); - int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(measuredWidth, - MeasureSpec.EXACTLY); - int measuredHeight = 0; - - //measure header or divider. when there is a header visible it acts as the divider - if (mHeader != null) { - ViewGroup.LayoutParams params = mHeader.getLayoutParams(); - if (params != null && params.height > 0) { - mHeader.measure(childWidthMeasureSpec, - MeasureSpec.makeMeasureSpec(params.height, MeasureSpec.EXACTLY)); - } else { - mHeader.measure(childWidthMeasureSpec, - MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)); - } - measuredHeight += mHeader.getMeasuredHeight(); - } else if (mDivider != null) { - measuredHeight += mDividerHeight; - } - - //measure item - ViewGroup.LayoutParams params = mItem.getLayoutParams(); - if (params != null && params.height > 0) { - mItem.measure(childWidthMeasureSpec, - MeasureSpec.makeMeasureSpec(params.height, MeasureSpec.EXACTLY)); - } else { - mItem.measure(childWidthMeasureSpec, - MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)); - } - measuredHeight += mItem.getMeasuredHeight(); - - setMeasuredDimension(measuredWidth, measuredHeight); - } - - @Override - protected void onLayout(boolean changed, int l, int t, int r, int b) { - - l = 0; - t = 0; - r = getWidth(); - b = getHeight(); - - if (mHeader != null) { - int headerHeight = mHeader.getMeasuredHeight(); - mHeader.layout(l, t, r, headerHeight); - mItemTop = headerHeight; - mItem.layout(l, headerHeight, r, b); - } else if (mDivider != null) { - mDivider.setBounds(l, t, r, mDividerHeight); - mItemTop = mDividerHeight; - mItem.layout(l, mDividerHeight, r, b); - } else { - mItemTop = t; - mItem.layout(l, t, r, b); - } - } - - @Override - protected void dispatchDraw(Canvas canvas) { - super.dispatchDraw(canvas); - if (mHeader == null && mDivider != null) { - // Drawable.setBounds() does not seem to work pre-honeycomb. So have - // to do this instead - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) { - canvas.clipRect(0, 0, getWidth(), mDividerHeight); - } - mDivider.draw(canvas); - } - } -} diff --git a/libraries/StickyListHeaders/library/src/se/emilsjolander/stickylistheaders/WrapperViewList.java b/libraries/StickyListHeaders/library/src/se/emilsjolander/stickylistheaders/WrapperViewList.java deleted file mode 100644 index 3d68e98db..000000000 --- a/libraries/StickyListHeaders/library/src/se/emilsjolander/stickylistheaders/WrapperViewList.java +++ /dev/null @@ -1,175 +0,0 @@ -package se.emilsjolander.stickylistheaders; - -import java.lang.reflect.Field; -import java.util.ArrayList; -import java.util.List; - -import android.content.Context; -import android.graphics.Canvas; -import android.graphics.Rect; -import android.os.Build; -import android.view.View; -import android.widget.AbsListView; -import android.widget.ListView; - -class WrapperViewList extends ListView { - - interface LifeCycleListener { - void onDispatchDrawOccurred(Canvas canvas); - } - - private LifeCycleListener mLifeCycleListener; - private List<View> mFooterViews; - private int mTopClippingLength; - private Rect mSelectorRect = new Rect();// for if reflection fails - private Field mSelectorPositionField; - private boolean mClippingToPadding = true; - - public WrapperViewList(Context context) { - super(context); - - // Use reflection to be able to change the size/position of the list - // selector so it does not come under/over the header - try { - Field selectorRectField = AbsListView.class.getDeclaredField("mSelectorRect"); - selectorRectField.setAccessible(true); - mSelectorRect = (Rect) selectorRectField.get(this); - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { - mSelectorPositionField = AbsListView.class.getDeclaredField("mSelectorPosition"); - mSelectorPositionField.setAccessible(true); - } - } catch (NoSuchFieldException e) { - e.printStackTrace(); - } catch (IllegalArgumentException e) { - e.printStackTrace(); - } catch (IllegalAccessException e) { - e.printStackTrace(); - } - } - - @Override - public boolean performItemClick(View view, int position, long id) { - if (view instanceof WrapperView) { - view = ((WrapperView) view).mItem; - } - return super.performItemClick(view, position, id); - } - - private void positionSelectorRect() { - if (!mSelectorRect.isEmpty()) { - int selectorPosition = getSelectorPosition(); - if (selectorPosition >= 0) { - int firstVisibleItem = getFixedFirstVisibleItem(); - View v = getChildAt(selectorPosition - firstVisibleItem); - if (v instanceof WrapperView) { - WrapperView wrapper = ((WrapperView) v); - mSelectorRect.top = wrapper.getTop() + wrapper.mItemTop; - } - } - } - } - - private int getSelectorPosition() { - if (mSelectorPositionField == null) { // not all supported andorid - // version have this variable - for (int i = 0; i < getChildCount(); i++) { - if (getChildAt(i).getBottom() == mSelectorRect.bottom) { - return i + getFixedFirstVisibleItem(); - } - } - } else { - try { - return mSelectorPositionField.getInt(this); - } catch (IllegalArgumentException e) { - e.printStackTrace(); - } catch (IllegalAccessException e) { - e.printStackTrace(); - } - } - return -1; - } - - @Override - protected void dispatchDraw(Canvas canvas) { - positionSelectorRect(); - if (mTopClippingLength != 0) { - canvas.save(); - Rect clipping = canvas.getClipBounds(); - clipping.top = mTopClippingLength; - canvas.clipRect(clipping); - super.dispatchDraw(canvas); - canvas.restore(); - } else { - super.dispatchDraw(canvas); - } - mLifeCycleListener.onDispatchDrawOccurred(canvas); - } - - void setLifeCycleListener(LifeCycleListener lifeCycleListener) { - mLifeCycleListener = lifeCycleListener; - } - - @Override - public void addFooterView(View v) { - super.addFooterView(v); - if (mFooterViews == null) { - mFooterViews = new ArrayList<View>(); - } - mFooterViews.add(v); - } - - @Override - public boolean removeFooterView(View v) { - if (super.removeFooterView(v)) { - mFooterViews.remove(v); - return true; - } - return false; - } - - boolean containsFooterView(View v) { - if (mFooterViews == null) { - return false; - } - return mFooterViews.contains(v); - } - - void setTopClippingLength(int topClipping) { - mTopClippingLength = topClipping; - } - - int getFixedFirstVisibleItem() { - int firstVisibleItem = getFirstVisiblePosition(); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { - return firstVisibleItem; - } - - // first getFirstVisiblePosition() reports items - // outside the view sometimes on old versions of android - for (int i = 0; i < getChildCount(); i++) { - if (getChildAt(i).getBottom() >= 0) { - firstVisibleItem += i; - break; - } - } - - // work around to fix bug with firstVisibleItem being to high - // because list view does not take clipToPadding=false into account - // on old versions of android - if (!mClippingToPadding && getPaddingTop() > 0 && firstVisibleItem > 0) { - if (getChildAt(0).getTop() > 0) { - firstVisibleItem -= 1; - } - } - - return firstVisibleItem; - } - - @Override - public void setClipToPadding(boolean clipToPadding) { - mClippingToPadding = clipToPadding; - super.setClipToPadding(clipToPadding); - } - -} |