package com.cocosw.framework.core; import android.app.Activity; import android.os.Bundle; import android.support.v4.content.Loader; import android.support.v4.view.MenuItemCompat; import android.view.LayoutInflater; import android.view.MenuItem; import android.view.View; import android.widget.AbsListView; import com.cocosw.accessory.views.CocoBundle; import com.cocosw.framework.R; import com.cocosw.framework.exception.CocoException; import com.cocosw.framework.view.adapter.CocoAdapter; import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; /** * Paged ListFragment * <p/> * With a endless listview within, progress view and empty view is also supported. * All your code in listFragment can be easily used in this class. * <p/> * <p/> * Project: cocoframework * User: Liao Kai([email protected]) * Date: 13-12-19 * Time: 下午9:35 */ public abstract class PagedListFragment<T, A extends AbsListView> extends ListAdapterViewFragment<T, A> { private static final String TIME = "_pagedlist_time"; private static final String ENDED = "_pagedlist_ended"; protected AtomicBoolean ended = new AtomicBoolean(false); protected int time = 0; private View loadview = null; @Override protected void setupUI(final View view, final Bundle bundle) { super.setupUI(view, bundle); } @Override public void onDestroy() { super.onDestroy(); save(TIME, time); save(ENDED, ended); } @Override public void onAttach(Activity activity) { super.onAttach(activity); ended = load(ENDED); if (ended == null) { ended = new AtomicBoolean(false); time = 0; } else { time = load(TIME); } } @Override public void onLoadFinished(final Loader<List<T>> loader, final List<T> items) { final Exception exception = getException(loader); onStopLoading(); if (refresh != null) { MenuItemCompat.setActionView(refresh, null); } if (exception != null) { ended.set(true); showError(exception); showList(); return; } if (items != null && mAdapter != null && !items.isEmpty()) { if (time == 0) getAdapter().refresh(); getAdapter().add(items); } showList(); updateAdapter(); onLoaderDone(items); showLoading(); if (items == null || items.size() < pagedSize(time)) { ended.set(true); onAllDataLoaded(); hideLoading(); } time++; } @Override public final List<T> pendingData(Bundle args) throws Exception { return pendingPagedData(getIndex(args), time, pagedSize(time), args); } /** * Data will be load in each pages * * @param index current index, used for start point, can be changed in getLastIndex() * @param time batch number, or the page number. * @param size how many items need to be load, can be changed in pagedSize() * @param args @return * @throws Exception */ public abstract List<T> pendingPagedData(long index, int time, int size, Bundle args) throws Exception; @Override protected void showRefresh(final CocoException e) { super.showRefresh(e); } @Override protected CocoAdapter<T> createAdapter(final List<T> items) throws Exception { return createEndlessAdapter(items); } protected abstract CocoAdapter<T> createEndlessAdapter(List<T> items) throws Exception; private final Bundle bundel = new Bundle(); protected MenuItem refresh; @Override public void onScroll(final AbsListView view, final int firstVisibleItem, final int visibleItemCount, final int totalItemCount) { super.onScroll(view, firstVisibleItem, visibleItemCount, totalItemCount); if (ended.get()) { return; } if (getLoaderManager().hasRunningLoaders()) { return; } if (getList() != null && wrapAdapter != null) { if (getList().getLastVisiblePosition() + 1 >= wrapAdapter.getCount()) { loadmore(); } } } private void loadmore() { //q.v("start loading more"); ended.set(false); onStartLoading(); getLoaderManager() .restartLoader( this.hashCode(), CocoBundle.builder(bundel).setIndex(getLastIndex()) .getBundle(), this ); } @Override protected void refreshAction() { // ended.set(true); getList().setSelection(0); showLoading(); loadmore(); } @Override public void refresh() { time = 0; super.refresh(); } /** * This will be called when all data has been loaded */ protected void onAllDataLoaded() { } protected void showLoading() { if (loadview == null && getHeaderAdapter() != null) { loadview = getLoadingView(); getHeaderAdapter().addFooter(loadview); } } @Override protected void hideLoading() { if (loadview != null) { getHeaderAdapter().removeFooter(loadview); } loadview = null; } protected Long getLastIndex() { return (long) getAdapter().getCount(); } protected int pagedSize(final int time) { return 10; } @Override protected void onStartLoading() { super.onStartLoading(); if (refresh != null) { MenuItemCompat.setActionView(refresh, R.layout.indeterminate_progress_action); } } /** * helper method for getting index * * @param bundel * @return */ protected long getIndex(Bundle bundel) { return CocoBundle.builder(bundel).getIndex(); } /** * the loading view in footer area * * @return */ protected View getLoadingView() { return LayoutInflater.from(context).inflate(R.layout.footer, null); } }