package com.kth.baasio.helpcenter.ui.pulltorefresh;
import com.kth.baasio.helpcenter.R;
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.MotionEvent;
import android.view.View;
import android.widget.AbsListView;
import android.widget.FrameLayout;
import android.widget.ListAdapter;
import android.widget.ListView;
public class PullToRefreshListView extends PullToRefreshAdapterViewBase<ListView> {
private LoadingLayout mHeaderLoadingView;
private LoadingLayout mFooterLoadingView;
private FrameLayout mLvFooterLoadingFrame;
private boolean mAddedLvFooter = false;
public class InternalListView extends ListView implements EmptyViewMethodAccessor {
public InternalListView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public void setAdapter(ListAdapter adapter) {
// Add the Footer View at the last possible moment
if (!mAddedLvFooter && null != mLvFooterLoadingFrame) {
addFooterView(mLvFooterLoadingFrame, null, false);
mAddedLvFooter = true;
}
super.setAdapter(adapter);
}
@Override
public void setEmptyView(View emptyView) {
PullToRefreshListView.this.setEmptyView(emptyView);
}
@Override
public void setEmptyViewInternal(View emptyView) {
super.setEmptyView(emptyView);
}
public ContextMenuInfo getContextMenuInfo() {
return super.getContextMenuInfo();
}
@Override
public boolean performItemClick(View view, int position, long id) {
return super.performItemClick(view, position, id);
}
}
public PullToRefreshListView(Context context) {
super(context);
setDisableScrollingWhileRefreshing(false);
}
public PullToRefreshListView(Context context, int mode) {
super(context, mode);
setDisableScrollingWhileRefreshing(false);
}
public PullToRefreshListView(Context context, AttributeSet attrs) {
super(context, attrs);
setDisableScrollingWhileRefreshing(false);
}
@Override
public ContextMenuInfo getContextMenuInfo() {
return ((InternalListView)getRefreshableView()).getContextMenuInfo();
}
public void setReleaseLabel(String releaseLabel) {
super.setReleaseLabel(releaseLabel);
if (null != mHeaderLoadingView) {
mHeaderLoadingView.setReleaseLabel(releaseLabel);
}
if (null != mFooterLoadingView) {
mFooterLoadingView.setReleaseLabel(releaseLabel);
}
}
// 05.25 유미형님. 시간 보여주지 말자.
public void setTimeLable() {
super.setTimeLabel();
// if (null != mHeaderLoadingView) {
// mHeaderLoadingView.setTimeText();
// }
// if (null != mFooterLoadingView) {
// mFooterLoadingView.setTimeText();
// }
}
public void setPullLabel(String pullLabel) {
super.setPullLabel(pullLabel);
if (null != mHeaderLoadingView) {
mHeaderLoadingView.setPullLabel(pullLabel);
}
if (null != mFooterLoadingView) {
mFooterLoadingView.setPullLabel(pullLabel);
}
}
public void setRefreshingLabel(String refreshingLabel) {
super.setRefreshingLabel(refreshingLabel);
if (null != mHeaderLoadingView) {
mHeaderLoadingView.setRefreshingLabel(refreshingLabel);
}
if (null != mFooterLoadingView) {
mFooterLoadingView.setRefreshingLabel(refreshingLabel);
}
}
@Override
protected final ListView createRefreshableView(Context context, AttributeSet attrs) {
ListView lv = new InternalListView(context, attrs);
final int mode = getMode();
// Loading View Strings
String pullLabel = context.getString(R.string.pull_to_refresh_pull_label);
String refreshingLabel = null;// context.getString(R.string.pull_to_refresh_refreshing_label);
String releaseLabel = context.getString(R.string.pull_to_refresh_release_label);
// Get Styles from attrs
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.PullToRefresh);
// Add Loading Views
if (mode == MODE_PULL_DOWN_TO_REFRESH || mode == MODE_BOTH) {
FrameLayout frame = new FrameLayout(context);
mHeaderLoadingView = new LoadingLayout(context, MODE_PULL_DOWN_TO_REFRESH,
releaseLabel, pullLabel, refreshingLabel, a);
frame.addView(mHeaderLoadingView, FrameLayout.LayoutParams.FILL_PARENT,
FrameLayout.LayoutParams.WRAP_CONTENT);
mHeaderLoadingView.setVisibility(View.GONE);
lv.addHeaderView(frame, null, false);
mLvFooterLoadingFrame = new FrameLayout(context);
mFooterLoadingView = new LoadingLayoutFooter(context);
mLvFooterLoadingFrame.addView(mFooterLoadingView, FrameLayout.LayoutParams.FILL_PARENT,
FrameLayout.LayoutParams.WRAP_CONTENT);
mFooterLoadingView.setVisibility(View.GONE);
}
if (mode == MODE_PULL_UP_TO_REFRESH || mode == MODE_BOTH) {
mLvFooterLoadingFrame = new FrameLayout(context);
mFooterLoadingView = new LoadingLayout(context, MODE_PULL_UP_TO_REFRESH, releaseLabel,
pullLabel, refreshingLabel, a);
mLvFooterLoadingFrame.addView(mFooterLoadingView, FrameLayout.LayoutParams.FILL_PARENT,
FrameLayout.LayoutParams.WRAP_CONTENT);
mFooterLoadingView.setVisibility(View.GONE);
}
a.recycle();
// Set it to this so it can be used in ListActivity/ListFragment
lv.setId(android.R.id.list);
return lv;
}
@Override
protected void setRefreshingInternal(boolean doScroll) {
// If we're not showing the Refreshing view, or the list is empty, then
// the header/footer views won't show so we use the
// normal method
ListAdapter adapter = mRefreshableView.getAdapter();
if (!getShowViewWhileRefreshing() || null == adapter || adapter.isEmpty()) {
super.setRefreshingInternal(doScroll);
return;
}
super.setRefreshingInternal(false);
final LoadingLayout originalLoadingLayout, listViewLoadingLayout;
final int selection, scrollToY;
switch (getCurrentMode()) {
case MODE_PULL_UP_TO_REFRESH:
originalLoadingLayout = getFooterLayout();
listViewLoadingLayout = mFooterLoadingView;
selection = mRefreshableView.getCount() - 1;
scrollToY = getScrollY() - getHeaderHeight();
break;
case MODE_PULL_DOWN_TO_REFRESH:
default:
originalLoadingLayout = getHeaderLayout();
listViewLoadingLayout = mHeaderLoadingView;
selection = 0;
scrollToY = getScrollY() + getHeaderHeight();
break;
}
if (doScroll) {
// We scroll slightly so that the ListView's header/footer is at the
// same Y position as our normal header/footer
setHeaderScroll(scrollToY);
}
// Hide our original Loading View
originalLoadingLayout.setVisibility(View.INVISIBLE);
// Show the ListView Loading View and set it to refresh
listViewLoadingLayout.setVisibility(View.VISIBLE);
listViewLoadingLayout.refreshing();
if (doScroll) {
// Make sure the ListView is scrolled to show the loading
// header/footer
mRefreshableView.setSelection(selection);
// Smooth scroll as normal
smoothScrollTo(0);
}
}
@Override
protected void resetHeader() {
// If we're not showing the Refreshing view, or the list is empty, then
// the header/footer views won't show so we use the
// normal method
ListAdapter adapter = mRefreshableView.getAdapter();
if (!getShowViewWhileRefreshing() || null == adapter || adapter.isEmpty()) {
super.resetHeader();
return;
}
LoadingLayout originalLoadingLayout;
LoadingLayout listViewLoadingLayout;
// int scrollToHeight = getHeaderHeight();
int selection;
switch (getCurrentMode()) {
case MODE_PULL_UP_TO_REFRESH:
originalLoadingLayout = getFooterLayout();
listViewLoadingLayout = mFooterLoadingView;
selection = mRefreshableView.getCount() - 1;
break;
case MODE_PULL_DOWN_TO_REFRESH:
default:
originalLoadingLayout = getHeaderLayout();
listViewLoadingLayout = mHeaderLoadingView;
// scrollToHeight *= -1;
selection = 0;
break;
}
originalLoadingLayout.setVisibility(View.VISIBLE);
mRefreshableView.dispatchTouchEvent(MotionEvent.obtain(0, 0, MotionEvent.ACTION_CANCEL,
100.0f, 100.0f, 0));
if (getState() != MANUAL_REFRESHING && mRefreshableView.getFirstVisiblePosition() == 0) {
mRefreshableView.setSelection(selection);
setHeaderScroll(-mRefreshableView.getChildAt(0).getBottom());
} else if (mRefreshableView.getFirstVisiblePosition() != 0) {
mRefreshableView.setSelection(selection);
}
// Hide the ListView Header/Footer
listViewLoadingLayout.setVisibility(View.GONE);
super.resetHeader();
}
protected int getNumberInternalHeaderViews() {
int count = 0;
if (mRefreshableView instanceof ListView) {
count = mRefreshableView.getHeaderViewsCount();
}
return null != mHeaderLoadingView ? count++ : 0;
}
protected int getNumberInternalFooterViews() {
int count = 0;
if (mRefreshableView instanceof ListView) {
count = mRefreshableView.getFooterViewsCount();
}
return null != mFooterLoadingView ? count++ : 0;
}
private boolean mHasMoreData = false;
private boolean mIsLoadingData = false;
public void setHasMoreData(boolean hasMoreData) {
mHasMoreData = hasMoreData;
}
public boolean hasMoreData() {
return mHasMoreData;
}
public void setIsLoading(boolean isLoading) {
mIsLoadingData = isLoading;
}
public boolean getIsLoading() {
return mIsLoadingData;
}
int mFirstVisibleItem = -1;
int mCurrentTopChild = -1;
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
int totalItemCount) {
int currentChildTop = 0;
if (visibleItemCount > 0) {
currentChildTop = view.getChildAt(0).getTop();
if (mFirstVisibleItem == 0 && currentChildTop == 0) {
if (mOnFirstItemVisibleListener != null)
mOnFirstItemVisibleListener.onFirstItemVisible();
} else {
if (mOnDirectionListener != null) {
if (mFirstVisibleItem > firstVisibleItem) {
mOnDirectionListener.onUp();
} else if (mFirstVisibleItem == firstVisibleItem) {
if (mCurrentTopChild > currentChildTop
&& mCurrentTopChild - currentChildTop > 5) {
// before data
mOnDirectionListener.onDown();
} else if (mCurrentTopChild < currentChildTop
&& currentChildTop - mCurrentTopChild > 5) {
// loading data
mOnDirectionListener.onUp();
}
} else if (mFirstVisibleItem < firstVisibleItem) {
mOnDirectionListener.onDown();
}
}
}
}
int lastInScreen = firstVisibleItem + visibleItemCount;
if (visibleItemCount > 0 && (lastInScreen == totalItemCount)) {
// only process first event
if (mHasMoreData && !mIsLoadingData) {
mIsLoadingData = true;
mOnRefreshListener.onUpdate();
if (null != mFooterLoadingView) {
mFooterLoadingView.setVisibility(View.VISIBLE);
}
} else if (!mHasMoreData && !mIsLoadingData) {
if (mOnLastItemVisibleListener != null) {
mOnLastItemVisibleListener.onLastItemVisible();
}
}
}
mFirstVisibleItem = firstVisibleItem;
mCurrentTopChild = currentChildTop;
}
public void setFooterGone() {
if (null != mFooterLoadingView) {
mFooterLoadingView.setVisibility(View.GONE);
mFooterLoadingView.invalidate();
}
}
public void setFooterVisible() {
if (null != mFooterLoadingView) {
mFooterLoadingView.setVisibility(View.VISIBLE);
mFooterLoadingView.invalidate();
}
}
}