package com.ch_linghu.fanfoudroid; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import android.app.SearchManager; import android.content.Intent; import android.os.Bundle; import android.text.TextUtils; import android.util.Log; import android.view.Menu; import android.view.View; import android.widget.ListView; import android.widget.ProgressBar; import com.ch_linghu.fanfoudroid.data.Tweet; import com.ch_linghu.fanfoudroid.fanfou.Query; import com.ch_linghu.fanfoudroid.fanfou.QueryResult; import com.ch_linghu.fanfoudroid.http.HttpException; import com.ch_linghu.fanfoudroid.task.GenericTask; import com.ch_linghu.fanfoudroid.task.AbstractTaskAdapter; import com.ch_linghu.fanfoudroid.task.ITaskListener; import com.ch_linghu.fanfoudroid.task.TaskParams; import com.ch_linghu.fanfoudroid.task.TaskResult; import com.ch_linghu.fanfoudroid.ui.base.ListBaseView; import com.ch_linghu.fanfoudroid.ui.module.SimpleFeedback; import com.ch_linghu.fanfoudroid.ui.module.TweetAdapter; import com.ch_linghu.fanfoudroid.ui.module.TweetArrayAdapter; import com.ch_linghu.fanfoudroid.R; import com.markupartist.android.widget.PullToRefreshListView; import com.markupartist.android.widget.PullToRefreshListView.OnRefreshListener; public class SearchResultActivity extends ListBaseView { private static final String TAG = "SearchActivity"; // Views. private PullToRefreshListView mTweetList; private View mListFooter; private ProgressBar loadMoreGIF; // State. private String mSearchQuery; private ArrayList<Tweet> mTweets; private TweetArrayAdapter mAdapter; private int mNextPage = 1; private String mLastId = null; private boolean mIsGetMore = false; private static class State { State(SearchResultActivity activity) { mTweets = activity.mTweets; mNextPage = activity.mNextPage; mLastId = activity.mLastId; } public ArrayList<Tweet> mTweets; public int mNextPage; public String mLastId; } // Tasks. private GenericTask mSearchTask; private ITaskListener mSearchTaskListener = new AbstractTaskAdapter() { @Override public void onPreExecute(GenericTask task) { if (mIsGetMore){ loadMoreGIF.setVisibility(View.VISIBLE); } if (mNextPage == 1) { updateProgress(getString(R.string.page_status_refreshing)); } else { updateProgress(getString(R.string.page_status_refreshing)); } mTweetList.prepareForRefresh(); } @Override public void onProgressUpdate(GenericTask task, Object param) { draw(); } @Override public void onPostExecute(GenericTask task, TaskResult result) { loadMoreGIF.setVisibility(View.GONE); mTweetList.onRefreshComplete(); if (result == TaskResult.AUTH_ERROR) { logout(); } else if (result == TaskResult.OK) { draw(); if (!mIsGetMore){ mTweetList.setSelection(1); } } else { // Do nothing. } updateProgress(""); } @Override public String getName() { return "SearchTask"; } }; @Override protected boolean _onCreate(Bundle savedInstanceState) { if (super._onCreate(savedInstanceState)) { Intent intent = getIntent(); // Assume it's SEARCH. // String action = intent.getAction(); mSearchQuery = intent.getStringExtra(SearchManager.QUERY); if (TextUtils.isEmpty(mSearchQuery)) { mSearchQuery = intent.getData().getLastPathSegment(); } mNavbar.setHeaderTitle(mSearchQuery); setTitle(mSearchQuery); State state = (State) getLastNonConfigurationInstance(); if (state != null) { mTweets = state.mTweets; mNextPage = state.mNextPage; mLastId = state.mLastId; draw(); } else { doSearch(false); } return true; } else { return false; } } @Override protected int getLayoutId() { return R.layout.main; } @Override protected void onResume() { super.onResume(); checkIsLogedIn(); } @Override public Object onRetainNonConfigurationInstance() { return createState(); } private synchronized State createState() { return new State(this); } @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); } @Override protected void onDestroy() { Log.d(TAG, "onDestroy."); if (mSearchTask != null && mSearchTask.getStatus() == GenericTask.Status.RUNNING) { mSearchTask.cancel(true); } super.onDestroy(); } // UI helpers. private void updateProgress(String progress) { mProgressText.setText(progress); } @Override protected void draw() { mAdapter.refresh(mTweets); } private void doSearch(boolean isGetMore) { Log.d(TAG, "Attempting search."); if (mSearchTask != null && mSearchTask.getStatus() == GenericTask.Status.RUNNING) { return; } else { mIsGetMore = isGetMore; mSearchTask = new SearchTask(); mSearchTask.setFeedback(mFeedback); mSearchTask.setListener(mSearchTaskListener); mSearchTask.execute(); } } private class SearchTask extends GenericTask { ArrayList<Tweet> mTweets = new ArrayList<Tweet>(); @Override protected TaskResult _doInBackground(TaskParams... params) { QueryResult result; try { Query query = new Query(mSearchQuery); if (!TextUtils.isEmpty(mLastId)) { query.setMaxId(mLastId); } result = getApi().search(query);// .search(mSearchQuery, // mNextPage); } catch (HttpException e) { Log.e(TAG, e.getMessage(), e); return TaskResult.IO_ERROR; } List<com.ch_linghu.fanfoudroid.fanfou.Status> statuses = result .getStatus(); HashSet<String> imageUrls = new HashSet<String>(); publishProgress(SimpleFeedback.calProgressBySize(40, 20, statuses)); for (com.ch_linghu.fanfoudroid.fanfou.Status status : statuses) { if (isCancelled()) { return TaskResult.CANCELLED; } Tweet tweet; tweet = Tweet.create(status); mLastId = tweet.id; mTweets.add(tweet); imageUrls.add(tweet.profileImageUrl); if (isCancelled()) { return TaskResult.CANCELLED; } } addTweets(mTweets); // if (isCancelled()) { // return TaskResult.CANCELLED; // } // // publishProgress(); // // // TODO: what if orientation change? // ImageManager imageManager = getImageManager(); // MemoryImageCache imageCache = new MemoryImageCache(); // // for (String imageUrl : imageUrls) { // if (!Utils.isEmpty(imageUrl)) { // // Fetch image to cache. // try { // Bitmap bitmap = imageManager.fetchImage(imageUrl); // imageCache.put(imageUrl, bitmap); // } catch (IOException e) { // Log.e(TAG, e.getMessage(), e); // } // } // // if (isCancelled()) { // return TaskResult.CANCELLED; // } // } // // addImages(imageCache); return TaskResult.OK; } } @Override public boolean onCreateOptionsMenu(Menu menu) { return super.onCreateOptionsMenu(menu); } public void doGetMore() { if (!isLastPage()) { doSearch(true); } } public boolean isLastPage() { return mNextPage == -1; } @Override protected void adapterRefresh() { mAdapter.refresh(mTweets); } private synchronized void addTweets(ArrayList<Tweet> tweets) { if (tweets.size() == 0) { mNextPage = -1; return; } mTweets.addAll(tweets); ++mNextPage; } @Override protected String getActivityTitle() { return mSearchQuery; } @Override protected Tweet getContextItemTweet(int position) { if (position >= 1 && position <= mAdapter.getCount()) { Tweet item = (Tweet) mAdapter.getItem(position - 1); if (item == null) { return null; } else { return item; } } else { return null; } } @Override protected TweetAdapter getTweetAdapter() { return mAdapter; } @Override protected ListView getTweetList() { return mTweetList; } @Override protected void updateTweet(Tweet tweet) { // TODO Simple and stupid implementation for (Tweet t : mTweets) { if (t.id.equals(tweet.id)) { t.favorited = tweet.favorited; break; } } } @Override protected boolean useBasicMenu() { return true; } @Override protected void setupState() { mTweets = new ArrayList<Tweet>(); mTweetList = (PullToRefreshListView) findViewById(R.id.tweet_list); mAdapter = new TweetArrayAdapter(this); mTweetList.setAdapter(mAdapter); mTweetList.setOnRefreshListener(new OnRefreshListener(){ @Override public void onRefresh(){ doRetrieve(); } }); // Add Footer to ListView mListFooter = View.inflate(this, R.layout.listview_footer, null); mTweetList.addFooterView(mListFooter, null, true); loadMoreGIF = (ProgressBar) findViewById(R.id.rectangleProgressBar); } @Override public void doRetrieve() { doSearch(false); } @Override protected void specialItemClicked(int position) { // 注意 mTweetAdapter.getCount 和 mTweetList.getCount的区别 // 前者仅包含数据的数量(不包括foot和head),后者包含foot和head // 因此在同时存在foot和head的情况下,list.count = adapter.count + 2 if (position == 0) { doRetrieve(); } else if (position == mTweetList.getCount() - 1) { // 最后一个Item(footer) doGetMore(); } } }