package net.oschina.gitapp.ui.basefragment; import java.util.ArrayList; import java.util.List; import net.oschina.gitapp.AppContext; import net.oschina.gitapp.R; import net.oschina.gitapp.bean.Entity; import net.oschina.gitapp.bean.MessageData; import net.oschina.gitapp.bean.PageList; import net.oschina.gitapp.common.DataRequestThreadHandler; import net.oschina.gitapp.widget.NewDataToast; import android.app.Activity; import android.os.Bundle; import android.support.v4.widget.SwipeRefreshLayout; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.AbsListView.OnScrollListener; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.AbsListView; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.ListView; import android.widget.ProgressBar; import android.widget.TextView; /** * 说明 下拉刷新界面的基类 */ public abstract class BaseSwipeRefreshFragment<Data extends Entity, Result extends PageList<Data>> extends BaseFragment implements SwipeRefreshLayout.OnRefreshListener, OnItemClickListener, OnScrollListener { // 没有状态 public static final int LISTVIEW_ACTION_NONE = -1; // 更新状态,不显示toast public static final int LISTVIEW_ACTION_UPDATE = 0; // 初始化时,加载缓存状态 public static final int LISTVIEW_ACTION_INIT = 1; // 刷新状态,显示toast public static final int LISTVIEW_ACTION_REFRESH = 2; // 下拉到底部时,获取下一页的状态 public static final int LISTVIEW_ACTION_SCROLL = 3; static final int STATE_NONE = -1; static final int STATE_LOADING = 0; static final int STATE_LOADED = 1; protected AppContext mApplication; protected SwipeRefreshLayout mSwipeRefreshLayout; protected ListView mListView; private View mHeaderView; private View mFooterView; private BaseAdapter mAdapter; private ProgressBar mLoading; private View mEmpty; private ImageView mEmptyImage;// 图像 private TextView mEmptyMessage;// 消息文字 private View mFooterProgressBar; private TextView mFooterTextView; private List<Data> mDataList = new ArrayList<Data>(); // 当前页面已加载的数据总和 private int mSumData; // 当前加载状态 private int mState = STATE_NONE; // UI状态 private int mListViewAction = LISTVIEW_ACTION_NONE; // 当前数据状态,如果是已经全部加载,则不再执行滚动到底部就加载的情况 private int mMessageState = MessageData.MESSAGE_STATE_MORE; private boolean isPauseLife = true; private DataRequestThreadHandler mRequestThreadHandler = new DataRequestThreadHandler(); @Override public void onAttach(Activity activity) { super.onAttach(activity); mApplication = getGitApplication(); } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mAdapter = getAdapter(mDataList); } @Override public void onPause() { super.onPause(); isPauseLife = true; } @Override public void onResume() { super.onResume(); isPauseLife = false; } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); } @Override public void onDestroy() { super.onDestroy(); mRequestThreadHandler.quit(); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { mHeaderView = getHeaderView(inflater); mFooterView = inflater.inflate(R.layout.listview_footer, null); mFooterProgressBar = mFooterView .findViewById(R.id.listview_foot_progress); mFooterTextView = (TextView) mFooterView .findViewById(R.id.listview_foot_more); return inflater.inflate(R.layout.fragment_base_swiperefresh, null); } @Override public void onViewCreated(View view, Bundle savedInstanceState) { initView(view); setupListView(); // viewpager划动到第三页,会将第一页的界面销毁,这里判断是初始状态,还是划画后再次加载 if (mState == STATE_LOADED && mAdapter.isEmpty()) { setFooterNoMoreState(); } else if (mState == STATE_LOADED && mAdapter.getCount() < AppContext.PAGE_SIZE) { setFooterFullState(); } // 正在刷新的状态 if (mListViewAction == LISTVIEW_ACTION_REFRESH) { setSwipeRefreshLoadingState(); } loadList(1, LISTVIEW_ACTION_INIT); } private void initView(View view) { mSwipeRefreshLayout = (SwipeRefreshLayout) view .findViewById(R.id.fragment_swiperefreshlayout); mListView = (ListView) view.findViewById(R.id.fragment_listview); mSwipeRefreshLayout.setOnRefreshListener(this); mSwipeRefreshLayout.setColorScheme(R.color.swiperefresh_color1, R.color.swiperefresh_color2, R.color.swiperefresh_color3, R.color.swiperefresh_color4); mLoading = (ProgressBar) view .findViewById(R.id.fragment_swiperefresh_loading); mEmpty = view.findViewById(R.id.fragment_swiperefresh_empty); mEmptyImage = (ImageView) mEmpty.findViewById(R.id.data_empty_image); mEmptyMessage = (TextView) mEmpty.findViewById(R.id.data_empty_message); } /** 设置列表空数据时的显示信息 */ public void setEmptyInfo(int imageResId, int messageResId) { mEmptyImage.setBackgroundResource(imageResId); mEmptyMessage.setText(messageResId); } @Override public void setUserVisibleHint(boolean isVisibleToUser) { super.setUserVisibleHint(isVisibleToUser); } /** 获取HeaderView */ protected View getHeaderView(LayoutInflater inflater) { return null; } /** 初始化ListView */ protected void setupListView() { mListView.setOnScrollListener(this); mListView.setOnItemClickListener(this); mListView.addFooterView(mFooterView); mListView.setAdapter(mAdapter); if (mHeaderView != null) { mListView.addHeaderView(mHeaderView); } } /** 获取适配器 */ public abstract BaseAdapter getAdapter(List<Data> list); /** 异步加载数据 */ protected abstract MessageData<Result> asyncLoadList(int page, boolean reflash); @Override public void onRefresh() { loadList(1, LISTVIEW_ACTION_REFRESH); } /** 更新数据,不显示toast */ public void update() { loadList(1, LISTVIEW_ACTION_UPDATE); } /** 返回是否正在加载 */ public boolean isLoadding() { return mState == STATE_LOADING; } /** 加载下一页 */ protected void onLoadNextPage() { // 当前pageIndex int pageIndex = mSumData / AppContext.PAGE_SIZE + 1; loadList(pageIndex, LISTVIEW_ACTION_SCROLL); } /** * 加载数据 * * @param page * 页码 * @param action * 加载的触发事件 * */ void loadList(int page, int action) { mListViewAction = action; mRequestThreadHandler.request(page, new AsyncDataHandler(page, action)); } /** 设置顶部正在加载的状态 */ void setSwipeRefreshLoadingState() { if (mSwipeRefreshLayout != null) { mSwipeRefreshLayout.setRefreshing(true); // 防止多次重复刷新 mSwipeRefreshLayout.setEnabled(false); } onRefreshLoadingStatus(); } /** 设置顶部加载完毕的状态 */ void setSwipeRefreshLoadedState() { if (mSwipeRefreshLayout != null) { mSwipeRefreshLayout.setRefreshing(false); mSwipeRefreshLayout.setEnabled(true); } onRefreshLoadedStatus(); } /** 设置底部有错误的状态 */ void setFooterErrorState() { if (mFooterView != null) { mFooterProgressBar.setVisibility(View.GONE); mFooterTextView.setText(R.string.load_error); } } /** 设置底部有更多数据的状态 */ void setFooterHasMoreState() { if (mFooterView != null) { mFooterProgressBar.setVisibility(View.GONE); mFooterTextView.setText(R.string.load_more); } } /** 设置底部已加载全部的状态 */ void setFooterFullState() { if (mFooterView != null) { mFooterProgressBar.setVisibility(View.GONE); mFooterTextView.setText(R.string.load_full); } } /** 设置底部无数据的状态 */ void setFooterNoMoreState() { if (mFooterView != null) { mFooterProgressBar.setVisibility(View.GONE); mFooterTextView.setText(R.string.load_empty); } } /** 设置底部加载中的状态 */ void setFooterLoadingState() { if (mFooterView != null) { mFooterProgressBar.setVisibility(View.VISIBLE); mFooterTextView.setText(R.string.load_ing); } } @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { // 点击了底部 if (view == mFooterView) { return; } // 点击了顶部 if (mHeaderView == view) { return; } if (mHeaderView != null) { position = position - 1; } Data data = getData(position); onItemClick(position, data); } /** 点击了某个item */ public void onItemClick(int position, Data data) { } /** 正在加载的状态 */ public void onRefreshLoadingStatus() { } /** 加载完毕的状态 */ public void onRefreshLoadedStatus() { } /** * 返回某项的数据 * * @param position * 数据位置 * */ public Data getData(int position) { return mDataList.get(position); } public void beforeLoading(int action) { // 开始加载 mState = STATE_LOADING; if (action == LISTVIEW_ACTION_REFRESH) { setSwipeRefreshLoadingState(); } else if (action == LISTVIEW_ACTION_SCROLL) { setFooterLoadingState(); } } public void afterLoading() { } @Override public void onScrollStateChanged(AbsListView view, int scrollState) { if (mAdapter == null || mAdapter.getCount() == 0) { return; } // 数据已经全部加载,或数据为空时,或正在加载,不处理滚动事件 if (mMessageState == MessageData.MESSAGE_STATE_FULL || mMessageState == MessageData.MESSAGE_STATE_EMPTY || mState == STATE_LOADING) { return; } // 判断是否滚动到底部 boolean scrollEnd = false; try { if (view.getPositionForView(mFooterView) == view .getLastVisiblePosition()) scrollEnd = true; } catch (Exception e) { scrollEnd = false; } if (scrollEnd) { onLoadNextPage(); } } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { } // 加载数据 private class AsyncDataHandler implements DataRequestThreadHandler.AsyncDataHandler<MessageData<Result>> { private int mPage; private int mAction; AsyncDataHandler(int page, int action) { mAction = action; mPage = page; } @Override public void onPreExecute() { beforeLoading(mAction); } @Override public MessageData<Result> execute() { boolean refresh = true; if (mAction == LISTVIEW_ACTION_INIT) { refresh = false; } return asyncLoadList(mPage, refresh); } @Override public void onPostExecute(MessageData<Result> msg) { // 加载结束 mState = STATE_LOADED; if (mAction == LISTVIEW_ACTION_INIT) { mSwipeRefreshLayout.setVisibility(View.VISIBLE); mLoading.setVisibility(View.GONE); } // 如果动作是下拉刷新,则将刷新中的状态去掉 if (mAction == LISTVIEW_ACTION_REFRESH) { setSwipeRefreshLoadedState(); } // 更新全局的状态 if (mListViewAction == mAction) { mListViewAction = LISTVIEW_ACTION_NONE; } // 无数据的情况下(已经加载全部数据,与一开始没有数据) if (msg.state == MessageData.MESSAGE_STATE_EMPTY && mDataList.size() != 0) { msg.state = MessageData.MESSAGE_STATE_FULL; } if (msg.result != null && msg.result.getList().size() == 0) { msg.state = MessageData.MESSAGE_STATE_EMPTY; } // 记录最后的数据状态 mMessageState = msg.state; if (msg.state == MessageData.MESSAGE_STATE_EMPTY) { // 底部显示“暂无数据” setFooterNoMoreState(); return; } else if (msg.state == MessageData.MESSAGE_STATE_ERROR) { setFooterErrorState(); return; } else if (msg.state == MessageData.MESSAGE_STATE_FULL) { // 当页数少于要求的加载页数的时,可以判断是已经加载完,没有更多的数据 setFooterFullState(); } else if (msg.state == MessageData.MESSAGE_STATE_MORE) { // 有数据的情况下,底部显示“正在加载...” setFooterHasMoreState(); } Result result = msg.result; if (mPage == 1) { int newdata = 0; mSumData = result.getPageSize(); if (mAction == LISTVIEW_ACTION_REFRESH || mAction == LISTVIEW_ACTION_UPDATE) { if (mDataList.size() > 0) { // 计算新增数据条数 for (Data data1 : result.getList()) { boolean b = false; for (Data data2 : mDataList) { if (data1.getId().equalsIgnoreCase( data2.getId())) { b = true; break; } } if (!b) { newdata++; } } } else { newdata = result.getPageSize(); } if (mAction == LISTVIEW_ACTION_REFRESH && !isPauseLife) { // 提示新添加的数据条数 if (newdata > 0) { NewDataToast .makeText( getActivity(), getString( R.string.new_data_toast_message, newdata), mApplication.isAppSound()).show(); } else { NewDataToast.makeText(getActivity(), getString(R.string.new_data_toast_none), false).show(); } } } // 先清除原有数据 mDataList.clear(); // 加入最新的数据 mDataList.addAll(result.getList()); } else { mSumData += result.getPageSize(); if (mDataList.size() > 0) { for (Data data1 : result.getList()) { boolean b = false; for (Data data2 : mDataList) { if (data1.getId().equalsIgnoreCase(data2.getId())) { b = true; break; } } if (!b) { mDataList.add(data1); } } } else { // 加入新增的数据 mDataList.addAll(result.getList()); } } // 通知listview去刷新界面 mAdapter.notifyDataSetChanged(); } } // 清空数据 public void clearData() { mDataList.clear(); mAdapter.notifyDataSetChanged(); } }