package com.mcxiaoke.next.ui.endless;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.AbsListView;
import android.widget.ListAdapter;
import android.widget.ListView;
import com.mcxiaoke.next.ui.BuildConfig;
import com.mcxiaoke.next.ui.view.SimpleProgressView;
/**
* User: mcxiaoke
* Date: 13-8-14
* Time: 下午9:32
*/
public class EndlessListView extends ListView implements AbsListView.OnScrollListener,
EndlessAdapter.OnFooterStateChangeListener {
public static final String TAG = EndlessListView.class.getSimpleName();
public static final boolean DEBUG = BuildConfig.DEBUG;
public static enum RefreshMode {
AUTO, CLICK, NONE
}
public interface OnFooterRefreshListener {
void onFooterRefresh(EndlessListView listView);
void onFooterIdle(EndlessListView listView);
}
private SimpleProgressView mFooter;
private EndlessAdapter mEndlessAdapter;
private OnScrollListener mOnScrollListener;
private OnFooterRefreshListener mOnRefreshListener;
private int mFirstVisibleItem;
private int mVisibleItemCount;
private int mTotalItemCount;
private boolean mLoading = false;
private int mScrollState = SCROLL_STATE_IDLE;
private RefreshMode mRefreshMode = RefreshMode.AUTO;
public EndlessListView(Context context) {
super(context);
initialize(context);
}
public EndlessListView(Context context, AttributeSet attrs) {
super(context, attrs);
initialize(context);
}
public EndlessListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initialize(context);
}
private void initialize(Context context) {
// mGestureDetector = new GestureDetector(getContext(), new XYScrollDetector());
mFooter = new SimpleProgressView(context);
setFadingEdgeLength(0);
super.setOnScrollListener(this);
}
@Override
public void setOnScrollListener(OnScrollListener listener) {
mOnScrollListener = listener;
}
@Override
public void setAdapter(ListAdapter adapter) {
mEndlessAdapter = new EndlessAdapter(getContext(), adapter);
mEndlessAdapter.setFooterView(mFooter);
mEndlessAdapter.setFooterStateChangeListener(this);
super.setAdapter(mEndlessAdapter);
}
public void setOnFooterRefreshListener(OnFooterRefreshListener listener) {
mOnRefreshListener = listener;
}
public void setRefreshMode(RefreshMode refreshMode) {
if (DEBUG) {
Log.v(TAG, "setRefreshMode() mode=" + refreshMode);
}
mRefreshMode = refreshMode;
checkFooterClick();
}
public boolean isAutoRefresh() {
return RefreshMode.AUTO.equals(mRefreshMode);
}
public boolean isClickRefresh() {
return RefreshMode.CLICK.equals(mRefreshMode);
}
public RefreshMode getRefreshMode() {
return mRefreshMode;
}
public void showFooterText(int resId) {
if (DEBUG) {
Log.v(TAG, "showFooterText() text=" + getResources().getString(resId));
}
showFooterText(getResources().getString(resId));
}
public void showFooterText(CharSequence text) {
if (DEBUG) {
Log.v(TAG, "showFooterText() text=" + text);
}
mEndlessAdapter.setState(EndlessAdapter.FooterState.IDLE, true);
mFooter.showText(text);
}
/**
* 只显示进度圆圈,但是不回调onRefresh
*/
public void showFooterRefreshing() {
setRefreshing(false);
}
private void setRefreshing(boolean needNotify) {
if (DEBUG) {
Log.v(TAG, "setRefreshing() isRefreshing=" + isRefreshing());
}
if (isRefreshing()) {
return;
}
mEndlessAdapter.setState(EndlessAdapter.FooterState.PROGRESS, needNotify);
mFooter.showProgress();
}
public void showFooterEmpty() {
if (DEBUG) {
Log.v(TAG, "showFooterEmpty() isRefreshing=" + isRefreshing());
}
mEndlessAdapter.setState(EndlessAdapter.FooterState.NONE, true);
mFooter.showEmpty();
}
private boolean isRefreshing() {
return mEndlessAdapter.isRefreshing();
}
private void checkFooterClick() {
if (mFooter != null) {
if (isClickRefresh()) {
mFooter.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
setRefreshing(true);
}
});
} else {
mFooter.setOnClickListener(null);
}
}
}
private void onRefresh() {
if (mOnRefreshListener != null) {
mOnRefreshListener.onFooterRefresh(this);
}
}
private void onIdle() {
if (mOnRefreshListener != null) {
mOnRefreshListener.onFooterIdle(this);
}
}
private void onNone() {
if (mOnRefreshListener != null) {
mOnRefreshListener.onFooterIdle(this);
}
}
@Override
public void onFooterStateChanged(EndlessAdapter.FooterState state, EndlessAdapter adapter) {
if (EndlessAdapter.FooterState.PROGRESS.equals(state)) {
onRefresh();
} else if (EndlessAdapter.FooterState.IDLE.equals(state)) {
mLoading = false;
onIdle();
} else {
mLoading = false;
onNone();
}
}
private void checkRefresh() {
if (DEBUG) {
Log.v(TAG, "checkRefresh() getRefreshMode=" + getRefreshMode() + " isRefreshing=" + isRefreshing());
Log.v(TAG, "checkRefresh() mFirstVisibleItem=" + mFirstVisibleItem + " mVisibleItemCount=" + mVisibleItemCount);
Log.v(TAG, "checkRefresh() mTotalItemCount=" + mTotalItemCount);
}
if (!isAutoRefresh()) {
return;
}
if (isRefreshing()) {
return;
}
if (mTotalItemCount == 0 || mVisibleItemCount >= mTotalItemCount) {
return;
}
if (mFirstVisibleItem + mVisibleItemCount >= mTotalItemCount) {
mLoading = true;
setRefreshing(true);
}
}
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
if (mOnScrollListener != null) {
mOnScrollListener.onScrollStateChanged(view, scrollState);
}
mScrollState = scrollState;
if (DEBUG) {
Log.v(TAG, "onScrollStateChanged() scrollState=" + scrollState);
}
if (SCROLL_STATE_IDLE == mScrollState) {
checkRefresh();
}
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
if (mOnScrollListener != null) {
mOnScrollListener.onScroll(view, firstVisibleItem, visibleItemCount, totalItemCount);
}
mFirstVisibleItem = firstVisibleItem;
mVisibleItemCount = visibleItemCount;
mTotalItemCount = totalItemCount;
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return super.onInterceptTouchEvent(ev);
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
return super.onTouchEvent(ev);
}
}