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;
}
}