package com.kth.baasio.helpcenter.ui.pulltorefresh; import android.content.Context; import android.util.AttributeSet; import android.util.Log; import android.view.ContextMenu.ContextMenuInfo; import android.view.View; import android.view.ViewGroup; import android.view.ViewParent; import android.widget.AbsListView; import android.widget.AbsListView.OnScrollListener; import android.widget.FrameLayout; import android.widget.LinearLayout; public abstract class PullToRefreshAdapterViewBase<T extends AbsListView> extends PullToRefreshBase<T> implements OnScrollListener { protected int mLastSavedFirstVisibleItem = -1; private OnScrollListener mOnScrollListener; protected OnLastItemVisibleListener mOnLastItemVisibleListener; protected OnDirectionListener mOnDirectionListener; protected OnFirstItemVisibleListener mOnFirstItemVisibleListener; private View mEmptyView; private FrameLayout mRefreshableViewHolder; public PullToRefreshAdapterViewBase(Context context) { super(context); mRefreshableView.setOnScrollListener(this); } public PullToRefreshAdapterViewBase(Context context, int mode) { super(context, mode); mRefreshableView.setOnScrollListener(this); } public PullToRefreshAdapterViewBase(Context context, AttributeSet attrs) { super(context, attrs); mRefreshableView.setOnScrollListener(this); } abstract public ContextMenuInfo getContextMenuInfo(); public void onScroll(final AbsListView view, final int firstVisibleItem, final int visibleItemCount, final int totalItemCount) { if (null != mOnLastItemVisibleListener) { // detect if last item is visible if (visibleItemCount > 0 && (firstVisibleItem + visibleItemCount == totalItemCount)) { // only process first event if (firstVisibleItem != mLastSavedFirstVisibleItem) { mLastSavedFirstVisibleItem = firstVisibleItem; mOnLastItemVisibleListener.onLastItemVisible(); } } } if (null != mOnScrollListener) { mOnScrollListener.onScroll(view, firstVisibleItem, visibleItemCount, totalItemCount); } } public void onScrollStateChanged(final AbsListView view, final int scrollState) { if (null != mOnScrollListener) { mOnScrollListener.onScrollStateChanged(view, scrollState); } } /** * Sets the Empty View to be used by the Adapter View. We need it handle it * ourselves so that we can Pull-to-Refresh when the Empty View is shown. * Please note, you do <strong>not</strong> usually need to call this method * yourself. Calling setEmptyView on the AdapterView will automatically call * this method and set everything up. This includes when the Android * Framework automatically sets the Empty View based on it's ID. * * @param newEmptyView - Empty View to be used */ public final void setEmptyView(View newEmptyView) { // If we already have an Empty View, remove it if (null != mEmptyView) { mRefreshableViewHolder.removeView(mEmptyView); } if (null != newEmptyView) { // New view needs to be clickable so that Android recognizes it as a // target for Touch Events newEmptyView.setClickable(true); ViewParent newEmptyViewParent = newEmptyView.getParent(); if (null != newEmptyViewParent && newEmptyViewParent instanceof ViewGroup) { ((ViewGroup)newEmptyViewParent).removeView(newEmptyView); } mRefreshableViewHolder.addView(newEmptyView, ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT); if (mRefreshableView instanceof EmptyViewMethodAccessor) { ((EmptyViewMethodAccessor)mRefreshableView).setEmptyViewInternal(newEmptyView); } else { mRefreshableView.setEmptyView(newEmptyView); } } } public final void setOnLastItemVisibleListener(OnLastItemVisibleListener listener) { mOnLastItemVisibleListener = listener; } public void setOnScrollListener(OnScrollListener listener) { mOnScrollListener = listener; } public final void setOnFirstItemVisibleListener(OnFirstItemVisibleListener listener) { mOnFirstItemVisibleListener = listener; } public final void setOnDirectionListener(OnDirectionListener listener) { mOnDirectionListener = listener; } protected void addRefreshableView(Context context, T refreshableView) { mRefreshableViewHolder = new FrameLayout(context); mRefreshableViewHolder.addView(refreshableView, ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT); addView(mRefreshableViewHolder, new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, 0, 1.0f)); }; protected boolean isReadyForPullDown() { return isFirstItemVisible(); } protected boolean isReadyForPullUp() { return isLastItemVisible(); } private boolean isFirstItemVisible() { // if (mRefreshableView.getCount() <= getNumberInternalViews()) { // return true; // } else if (mRefreshableView.getFirstVisiblePosition() == 0) { final View firstVisibleChild = mRefreshableView.getChildAt(0); if (firstVisibleChild != null) { return firstVisibleChild.getTop() >= mRefreshableView.getTop(); } } return false; } private boolean isLastItemVisible() { final int count = mRefreshableView.getCount(); final int lastVisiblePosition = mRefreshableView.getLastVisiblePosition(); if (DEBUG) { Log.d(LOG_TAG, "isLastItemVisible. Count: " + count + " Last Visible Pos: " + lastVisiblePosition); } if (count <= getNumberInternalViews()) { return true; } else if (lastVisiblePosition == count - 1) { final int childIndex = lastVisiblePosition - mRefreshableView.getFirstVisiblePosition(); final View lastVisibleChild = mRefreshableView.getChildAt(childIndex); if (lastVisibleChild != null) { return lastVisibleChild.getBottom() <= mRefreshableView.getBottom(); } } return false; } protected int getNumberInternalViews() { return getNumberInternalHeaderViews() + getNumberInternalFooterViews(); } /** * Returns the number of Adapter View Header Views. This will always return * 0 for non-ListView views. * * @return 0 for non-ListView views, possibly 1 for ListView */ protected int getNumberInternalHeaderViews() { return 0; } /** * Returns the number of Adapter View Footer Views. This will always return * 0 for non-ListView views. * * @return 0 for non-ListView views, possibly 1 for ListView */ protected int getNumberInternalFooterViews() { return 0; } }