package com.mcxiaoke.minicat.fragment;
import android.app.Activity;
import android.app.LoaderManager.LoaderCallbacks;
import android.content.Loader;
import android.database.Cursor;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.Parcelable;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v4.widget.SwipeRefreshLayout.OnRefreshListener;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.CursorAdapter;
import android.widget.ListView;
import android.widget.TextView;
import butterknife.ButterKnife;
import butterknife.InjectView;
import com.mcxiaoke.commons.view.endless.EndlessListView;
import com.mcxiaoke.minicat.AppContext;
import com.mcxiaoke.minicat.Cache;
import com.mcxiaoke.minicat.R;
import com.mcxiaoke.minicat.adapter.BaseCursorAdapter;
import com.mcxiaoke.minicat.controller.PopupController;
import com.mcxiaoke.minicat.dao.model.StatusModel;
import com.mcxiaoke.minicat.service.SyncService;
import com.mcxiaoke.minicat.ui.UIHelper;
import com.mcxiaoke.minicat.util.NetworkHelper;
import com.mcxiaoke.minicat.util.Utils;
import com.nostra13.universalimageloader.core.ImageLoader;
/**
* @author mcxiaoke
* @version 1.8 2012.03.19
*/
public abstract class SwipeRefreshListFragment extends AbstractListFragment
implements EndlessListView.OnFooterRefreshListener, OnItemLongClickListener,
LoaderCallbacks<Cursor> {
protected static final int LOADER_ID = 1;
private static final String TAG = SwipeRefreshListFragment.class
.getSimpleName();
@InjectView(R.id.root)
SwipeRefreshLayout mSwipeRefreshLayout;
@InjectView(R.id.list)
EndlessListView mListView;
boolean mDataLoaded;
volatile boolean busy;
private Parcelable mParcelable;
private BaseCursorAdapter mAdapter;
private Handler mHandler;
public SwipeRefreshListFragment() {
super();
// if (AppContext.DEBUG) {
// Log.v(TAG, "PullToRefreshListFragment() id=" + this);
// }
mHandler = new Handler();
}
protected static void showPopup(Activity context, final View view,
final Cursor c) {
if (c != null) {
final StatusModel s = StatusModel.from(c);
if (s != null) {
PopupController.showPopup(view, s, c);
}
}
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
// if (AppContext.DEBUG) {
// Log.v(TAG, "onAttach() isVisible=" + isVisible());
// }
}
@Override
public void startRefresh() {
if (AppContext.DEBUG) {
Log.v(TAG, "startRefresh() busy=" + busy + " " + this);
}
if (!AppContext.isVerified()) {
return;
}
if (NetworkHelper.isNotConnected(getActivity())) {
return;
}
if (!busy) {
busy = true;
doRefresh();
showRefreshIndicator(true);
}
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
}
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
return null;
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor newCursor) {
getAdapter().swapCursor(newCursor);
if (AppContext.DEBUG) {
Log.v(TAG, "onLoadFinished() adapter=" + mAdapter.getCount());
}
showFooterText();
checkRefresh();
}
@Override
public void onLoaderReset(Loader<Cursor> loader) {
if (AppContext.DEBUG) {
Log.v(TAG, "onLoaderReset()");
}
getAdapter().swapCursor(null);
}
private void setUp() {
mSwipeRefreshLayout.setColorSchemeResources(
R.color.color1,
R.color.color2,
R.color.color3, R.color.color4);
mSwipeRefreshLayout.setOnRefreshListener(new OnRefreshListener() {
@Override
public void onRefresh() {
refreshData();
}
});
mListView.setVerticalScrollBarEnabled(true);
mListView.setHorizontalScrollBarEnabled(false);
mListView.setFastScrollEnabled(false);
mListView.setOnItemClickListener(this);
mListView.setOverScrollMode(ListView.OVER_SCROLL_NEVER);
mListView.setLongClickable(false);
mListView.setOnFooterRefreshListener(this);
mListView.setOnScrollListener(new OnScrollListener() {
@Override
public void onScrollStateChanged(final AbsListView view, final int scrollState) {
if (scrollState == OnScrollListener.SCROLL_STATE_IDLE) {
ImageLoader.getInstance().resume();
} else {
ImageLoader.getInstance().pause();
}
}
@Override
public void onScroll(final AbsListView view, final int firstVisibleItem, final int visibleItemCount, final int totalItemCount) {
}
});
UIHelper.setListView(mListView);
}
@Override
public void onFooterRefresh(EndlessListView endlessListView) {
doFetch(true);
}
@Override
public void onFooterIdle(EndlessListView endlessListView) {
}
private void refreshData() {
doFetch(false);
showRefreshIndicator(true);
}
protected void showRefreshIndicator(final boolean show) {
if (mSwipeRefreshLayout != null) {
mSwipeRefreshLayout.setRefreshing(show);
}
}
private void showFooterText() {
if (mListView != null) {
if (getType() == StatusModel.TYPE_PUBLIC) {
mListView.showFooterEmpty();
} else {
if (getAdapter().isEmpty()) {
mListView.showFooterEmpty();
} else {
mListView.showFooterText(R.string.endless_footer_load_more);
}
}
}
}
@Override
public void onHiddenChanged(boolean hidden) {
super.onHiddenChanged(hidden);
// if (AppContext.DEBUG) {
// Log.v(TAG, "onHiddenChanged() hidden=" + hidden + " isVisible="
// + isVisible());
// }
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// if (AppContext.DEBUG) {
// Log.v(TAG, "onCreate() isVisible=" + isVisible());
// }
Bundle args = getArguments();
if (args != null) {
parseArguments(args);
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// if (AppContext.DEBUG) {
// Log.v(TAG, "onCreateView() isVisible=" + isVisible());
// }
final View view = inflater.inflate(R.layout.fm_pull_list, container, false);
ButterKnife.inject(this, view);
return view;
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
// if (AppContext.DEBUG) {
// Log.v(TAG, "onViewCreated() isVisible=" + isVisible());
// }
setUp();
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
// if (AppContext.DEBUG) {
// Log.v(TAG, "onActivityCreated() isVisible=" + isVisible());
// }
parseArguments(getArguments());
if (savedInstanceState != null) {
mParcelable = savedInstanceState.getParcelable("state");
}
mAdapter = (BaseCursorAdapter) onCreateAdapter();
mListView.setAdapter(mAdapter);
mListView.setOnScrollListener(mAdapter);
mListView.setRefreshMode(EndlessListView.RefreshMode.CLICK);
mListView.showFooterEmpty();
getLoaderManager().initLoader(LOADER_ID, null, this);
}
@Override
public void onStart() {
super.onStart();
// if (AppContext.DEBUG) {
// Log.v(TAG, "onStart() isVisible=" + isVisible());
// }
}
@Override
public void onResume() {
super.onResume();
if (mParcelable != null && mListView != null) {
mListView.onRestoreInstanceState(mParcelable);
mParcelable = null;
}
// if (AppContext.DEBUG) {
// Log.v(TAG, "onResume() isVisible=" + isVisible());
// }
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
if (mListView != null) {
mParcelable = mListView.onSaveInstanceState();
outState.putParcelable("state", mParcelable);
}
}
@Override
public void onPause() {
super.onPause();
// if (AppContext.DEBUG) {
// Log.v(TAG, "onPause() isVisible=" + isVisible());
// }
}
@Override
public void onStop() {
super.onStop();
// if (AppContext.DEBUG) {
// Log.v(TAG, "onStop() isVisible=" + isVisible());
// }
}
@Override
public void onDestroyView() {
super.onDestroyView();
// if (AppContext.DEBUG) {
// Log.v(TAG, "onDestroyView()");
// }
}
@Override
public void onDestroy() {
super.onDestroy();
// if (AppContext.DEBUG) {
// Log.v(TAG, "onDestroy()");
// }
}
@Override
public void onDetach() {
super.onDetach();
// if (AppContext.DEBUG) {
// Log.v(TAG, "onDetach() isVisible=" + isVisible());
// }
}
protected abstract void parseArguments(Bundle args);
protected abstract CursorAdapter onCreateAdapter();
protected abstract void doFetch(boolean doGetMore);
protected abstract int getType();
protected boolean shouldDelayRefresh() {
return false;
}
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view,
int position, long id) {
return true;
}
protected void doRefresh() {
if (AppContext.DEBUG) {
Log.v(TAG, "doRefresh()");
}
doFetch(false);
}
protected void doGetMore() {
if (AppContext.DEBUG) {
Log.v(TAG, "doGetMore()");
}
doFetch(true);
}
public Cursor getCursor() {
if (mAdapter != null) {
return mAdapter.getCursor();
}
return null;
}
@Override
public CursorAdapter getAdapter() {
return mAdapter;
}
@Override
public EndlessListView getListView() {
return mListView;
}
public void setSelection(int position) {
mListView.setSelection(position);
}
public void setEmptyView(View emptyView) {
mListView.setEmptyView(emptyView);
}
public void setEmptyText(CharSequence text) {
final TextView tv = new TextView(getActivity());
tv.setText(text);
mListView.setEmptyView(tv);
}
public void goTop() {
mListView.setSelection(0);
}
private void onSuccess(Bundle data) {
int count = data.getInt("count");
if (AppContext.DEBUG) {
Log.v(TAG, "onSuccess(data) count=" + count);
}
if (getType() == StatusModel.TYPE_HOME) {
Cache.sLastHomeRefresh = System.currentTimeMillis();
}
}
private void onError(Bundle data) {
if (AppContext.DEBUG) {
Log.v(TAG, "onSuccess()");
}
showFooterText();
String errorMessage = data.getString("error_message");
int errorCode = data.getInt("error_code");
if (!isAdded()) {
return;
}
Utils.notify(getActivity(), errorMessage);
}
private void onRefreshComplete() {
showFooterText();
showRefreshIndicator(false);
}
protected void checkRefresh() {
if (AppContext.DEBUG) {
Log.v(TAG, "checkRefresh() adapter.count=" + mAdapter.getCount() + " " + this);
}
if (mAdapter.isEmpty()) {
startRefresh();
return;
}
if (getType() == StatusModel.TYPE_HOME &&
System.currentTimeMillis() - Cache.sLastHomeRefresh > 30 * 60 * 1000L) {
startRefresh();
}
}
/**
* FetchService返回数据处理 根据resultData里面的type信息分别处理
*/
protected static class ResultHandler extends Handler {
private SwipeRefreshListFragment mFragment;
public ResultHandler(SwipeRefreshListFragment fragment) {
this.mFragment = fragment;
}
@Override
public void handleMessage(Message msg) {
Bundle data = msg.getData();
if (AppContext.DEBUG) {
Log.v(TAG, "handleMessage() data=" + data + " msg=" + msg);
}
mFragment.busy = false;
switch (msg.what) {
case SyncService.RESULT_SUCCESS:
mFragment.onSuccess(data);
break;
case SyncService.RESULT_ERROR:
mFragment.onError(data);
break;
default:
break;
}
mFragment.getBaseSupport().hideProgressIndicator();
mFragment.onRefreshComplete();
}
}
}