package com.cundong.izhihu.fragment; import java.io.IOException; import java.util.ArrayList; import uk.co.senab.actionbarpulltorefresh.extras.actionbarsherlock.PullToRefreshLayout; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.support.annotation.Nullable; import android.text.TextUtils; 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.OnItemClickListener; import android.widget.ListView; import android.widget.ProgressBar; import com.cundong.izhihu.Constants; import com.cundong.izhihu.R; import com.cundong.izhihu.ZhihuApplication; import com.cundong.izhihu.activity.NewsDetailActivity; import com.cundong.izhihu.adapter.NewsAdapter; import com.cundong.izhihu.db.NewsDataSource; import com.cundong.izhihu.entity.NewsListEntity; import com.cundong.izhihu.entity.NewsListEntity.NewsEntity; import com.cundong.izhihu.task.BaseGetNewsTask; import com.cundong.izhihu.task.BaseGetNewsTask.ResponseListener; import com.cundong.izhihu.task.GetLatestNewsTask; import com.cundong.izhihu.task.MyAsyncTask; import com.cundong.izhihu.util.GsonUtils; import com.cundong.izhihu.util.ListUtils; import com.cundong.izhihu.util.ZhihuUtils; public class NewsListFragment extends BaseFragment implements ResponseListener, OnItemClickListener { private ListView mListView; private ProgressBar mProgressBar; private NewsAdapter mAdapter = null; private ArrayList<NewsEntity> mNewsList = null; //上次listView滚动到最下方时,itemId private int mListViewPreLast = 0; private String mCurrentDate = null; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); new LoadCacheNewsTask().executeOnExecutor(MyAsyncTask.THREAD_POOL_EXECUTOR); new GetLatestNewsTask(getActivity(), this).executeOnExecutor(MyAsyncTask.THREAD_POOL_EXECUTOR); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_main, container, false); mPullToRefreshLayout = (PullToRefreshLayout) view.findViewById(R.id.ptr_layout); mListView = (ListView) view.findViewById(R.id.list); mListView.setOnItemClickListener(this); mProgressBar = (ProgressBar) view.findViewById(R.id.progress); return view; } @Override public void onActivityCreated(@Nullable Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); mListView.setOnScrollListener(new OnScrollListener() { @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { final int lastItem = firstVisibleItem + visibleItemCount; if (lastItem == totalItemCount) { if (mListViewPreLast != lastItem) { // to avoid multiple calls for mCurrentDate = ZhihuUtils.getBeforeDate(mCurrentDate); new GetMoreNewsTask(getActivity(), null).executeOnExecutor(MyAsyncTask.THREAD_POOL_EXECUTOR, mCurrentDate); mListViewPreLast = lastItem; } } } @Override public void onScrollStateChanged(AbsListView view, int scrollState) { } }); } private void setAdapter(ArrayList<NewsEntity> newsList) { if (mAdapter == null) { mAdapter = new NewsAdapter(getActivity(), newsList); mListView.setAdapter(mAdapter); } else { mAdapter.updateData(newsList); } } private void setListShown(boolean isListViewShown) { mListView.setVisibility(isListViewShown ? View.VISIBLE : View.GONE); mProgressBar.setVisibility(isListViewShown ? View.GONE : View.VISIBLE); } //读取缓存中的最新新闻 private class LoadCacheNewsTask extends MyAsyncTask<String, Void, NewsListEntity> { @Override protected NewsListEntity doInBackground(String... params) { NewsListEntity latestNewsEntity = ZhihuApplication.getDataSource().getLatestNews(); if (latestNewsEntity != null) { mCurrentDate = latestNewsEntity.date; ZhihuUtils.setReadStatus4NewsList(latestNewsEntity.stories); } return latestNewsEntity; } @Override protected void onPostExecute(NewsListEntity result) { super.onPostExecute(result); if(!isAdded()) return; if (result != null && !ListUtils.isEmpty(result.stories)) { NewsEntity tagNewsEntity = new NewsEntity(); tagNewsEntity.isTag = true; tagNewsEntity.title = result.date; mNewsList = new ArrayList<NewsEntity>(); mNewsList.add(tagNewsEntity); mNewsList.addAll(result.stories); setAdapter(mNewsList); } } } //下载过往的新闻 private class GetMoreNewsTask extends BaseGetNewsTask { public GetMoreNewsTask(Context context, ResponseListener listener) { super(context, listener); } @Override protected NewsListEntity doInBackground(String... params) { if (params.length == 0) return null; String theKey = params[0]; String oldContent = ((NewsDataSource) getDataSource()).getContent(theKey); NewsListEntity newsListEntity = null; if (!TextUtils.isEmpty(oldContent)) { newsListEntity = (NewsListEntity) GsonUtils.getEntity(oldContent, NewsListEntity.class); if (newsListEntity != null) { ZhihuUtils.setReadStatus4NewsList(newsListEntity.stories); } return newsListEntity; } else { String newContent = null; try { newContent = getUrl(Constants.Url.URLDEFORE + ZhihuUtils.getAddedDate(theKey)); newsListEntity = (NewsListEntity)GsonUtils.getEntity(newContent, NewsListEntity.class); isRefreshSuccess = !ListUtils.isEmpty(newsListEntity.stories); } catch (IOException e) { e.printStackTrace(); this.isRefreshSuccess = false; this.mException = e; } catch (Exception e) { e.printStackTrace(); this.isRefreshSuccess = false; this.mException = e; } isContentSame = checkIsContentSame(oldContent, newContent); if (isRefreshSuccess && !isContentSame) { ((NewsDataSource) getDataSource()).insertOrUpdateNewsList(Constants.NEWS_LIST, theKey, newContent); } if (newsListEntity != null) { ZhihuUtils.setReadStatus4NewsList(newsListEntity.stories); } return newsListEntity; } } @Override protected void onPostExecute(NewsListEntity result) { super.onPostExecute(result); if(!isAdded()) return; setListShown(true); mListViewPreLast = 0; if (mNewsList == null) { mNewsList = new ArrayList<NewsEntity>(); } if (result != null && !ListUtils.isEmpty(result.stories)) { NewsEntity tagNewsEntity = new NewsEntity(); tagNewsEntity.isTag = true; tagNewsEntity.title = result.date; mNewsList.add(tagNewsEntity); mNewsList.addAll(result.stories); setAdapter(mNewsList); } } } @Override public void onPreExecute() { } @Override public void onProgressUpdate(String value) { } @Override public void onPostExecute(NewsListEntity result) { if(!isAdded()) return; // Notify PullToRefreshLayout that the refresh has finished mPullToRefreshLayout.setRefreshComplete(); if (getView() != null) { // Show the list again setListShown(true); } if (result != null) { mNewsList = new ArrayList<NewsEntity>(); NewsEntity tagNewsEntity = new NewsEntity(); tagNewsEntity.isTag = true; tagNewsEntity.title = result.date; mNewsList.add(tagNewsEntity); mNewsList.addAll(result.stories); mCurrentDate = result.date; setAdapter(mNewsList); } } @Override public void onFail(Exception e) { if (getView() != null) { // Show the list again setListShown(true); } dealException(e); } @Override protected void doRefresh() { // Hide the list setListShown( mNewsList==null ||mNewsList.isEmpty() ? false : true ); new GetLatestNewsTask(getActivity(), this).executeOnExecutor(MyAsyncTask.THREAD_POOL_EXECUTOR); } @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { NewsEntity newsEntity = mNewsList != null ? mNewsList.get(position) : null; if (newsEntity == null) return; Intent intent = new Intent(); intent.putExtra("id", newsEntity.id); intent.putExtra("newsEntity", newsEntity); intent.setClass(getActivity(), NewsDetailActivity.class); startActivity(intent); new SetReadFlagTask(newsEntity).executeOnExecutor(MyAsyncTask.THREAD_POOL_EXECUTOR); } public void updateList() { new LoadCacheNewsTask().executeOnExecutor(MyAsyncTask.THREAD_POOL_EXECUTOR); } @Override protected void onRestoreState(Bundle savedInstanceState) { } @Override protected void onSaveState(Bundle outState) { } @Override protected void onFirstTimeLaunched() { } private class SetReadFlagTask extends MyAsyncTask<String, Void, Boolean> { private NewsEntity mNewsEntity; public SetReadFlagTask(NewsEntity newsEntity) { mNewsEntity = newsEntity; } @Override protected Boolean doInBackground(String... params) { return ZhihuApplication.getNewsReadDataSource().readNews(String.valueOf(mNewsEntity.id)); } @Override protected void onPostExecute(Boolean result) { super.onPostExecute(result); if (result) { ZhihuUtils.setReadStatus4NewsEntity(mNewsList, mNewsEntity); mAdapter.updateData(mNewsList); } } } }