package com.cinla.ringtone; import java.io.File; import java.util.ArrayList; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; import com.cinla.ringtone.ListStatusView.Status; import com.latest.ringtone.R; import android.app.ListActivity; import android.content.Context; import android.content.Intent; import android.os.AsyncTask; import android.os.Bundle; import android.os.Handler; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.Button; import android.widget.ImageView; import android.widget.ListView; import android.widget.ProgressBar; import android.widget.RatingBar; import android.widget.TextView; public class SearchListActivity extends ListActivity { private ProgressBar mProgressBar; private TextView mSearchMessage; private Button mRetryButton; // private SearchListFooterView mFooter; private SearchBar mSearchBar; private Mp3ListAdapter mAdapter; private Mp3ListWrapper mData; private MusicParser mFetcher; private FetchMp3ListTask mFetchMp3ListTask; private Handler mHandler = new Handler(); private int mSearchType; private String mSearchKey; private int mStartPos; private boolean mKeepFetching = true; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.search_list_activity); AdListener.createAds(this); mProgressBar = (ProgressBar) findViewById(R.id.search_progress); mSearchMessage = (TextView) findViewById(R.id.search_message); mRetryButton = (Button) findViewById(R.id.retry_button); mRetryButton.setOnClickListener(new RetryButtonClickListener()); // mFooter = new SearchListFooterView(this); // getListView().addFooterView(mFooter); // mFooter.setFocusable(false); // mFooter.getBtnNext().setOnClickListener(new NextButtonClickListener()); // mFooter.getBtnPre().setOnClickListener(new PrevButtonClickListener()); mSearchBar = new SearchBar(this); adjustSearchType(getIntent()); if (mSearchType==Constant.TYPE_KEY) { getListView().requestFocus(); } if (mSearchType!=Constant.TYPE_EMPTY) { startQuery(getIntent().getStringExtra(Constant.QUERY)); setLoadingStatus(); } else if (mSearchType==Constant.TYPE_EMPTY){ setHintStatus(); } } private void adjustSearchType(Intent intent) { Utils.D("in on NewIntent()"); mSearchType = intent.getIntExtra(Constant.SEARCH_TYPE, -1); mSearchKey = intent.getStringExtra(Constant.QUERY); switch (mSearchType) { case Constant.TYPE_EMPTY: break; case Constant.TYPE_KEY: if (getIntent().getBooleanExtra(Constant.HIDE_SEARCHBAR, false)) { mSearchBar.hide(); } break; case Constant.TYPE_ARTIST: mSearchBar.hide(); break; case Constant.TYPE_CATEGORY: mSearchBar.hide(); break; case Constant.TYPE_NEWEST: mSearchBar.hide(); break; case Constant.TYPE_TOP_DOWNLOAD: mSearchBar.hide(); break; default: break; } } @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); adjustSearchType(intent); Utils.D("in onNewIntent of SearchListActivity"); Utils.D("onNewIntent: "+intent.getStringExtra(Constant.QUERY)); startQuery(intent.getStringExtra(Constant.QUERY)); } @Override protected void onListItemClick(ListView l, View v, int position, long id) { // super.onListItemClick(l, v, position, id); try { if (position >= mData.size()) { return; } MusicInfo clickedMusicInfo = mData.get(position); String filePath = clickedMusicInfo.getFilePath(); String objPath = Utils.musicPathToObjPath(filePath); File file = new File(objPath); if (file.exists()) { clickedMusicInfo = Utils.readMusicInfoFromFile(objPath); } MusicPageActivity.startMusicPageActivity(this, clickedMusicInfo); } catch (Exception e) { } } public void startQuery(String keyWord) { mStartPos = 0; if (mData!=null) { mData.clear(); } if (mAdapter!=null) { mAdapter.notifyDataSetChanged(); } mData = null; mAdapter = null; mKeepFetching = true; continueFetch(keyWord, true); } public void continueFetch(String keyWord, boolean isNext) { if (mFetchMp3ListTask != null) { mFetchMp3ListTask.cancel(true); } mFetchMp3ListTask = new FetchMp3ListTask(isNext); mFetchMp3ListTask.execute(keyWord); } public void handleSearchResults(ArrayList<MusicInfo> mp3List) { if (mAdapter == null) { mAdapter = new Mp3ListAdapter(SearchListActivity.this, R.layout.result_item); setListAdapter(mAdapter); } int prevSelectionPos = getListView().getSelectedItemPosition(); if (mp3List != null) { if (mData == null) { mData = new Mp3ListWrapper(); } mData.append(mp3List); mAdapter.notifyDataSetChanged(); } getListView().setSelection(prevSelectionPos); } // A thread safe wrapper around ArrayList<MP3Info>. public final class Mp3ListWrapper { private ArrayList<MusicInfo> mMp3List; private ReadWriteLock lock = new ReentrantReadWriteLock(); private Lock r = lock.readLock(); private Lock w = lock.writeLock(); public Mp3ListWrapper() { mMp3List = new ArrayList<MusicInfo>(); } public void clear() { w.lock(); try { mMp3List.clear(); if (mAdapter != null) mAdapter.notifyDataSetInvalidated(); } finally { w.unlock(); } } public void add(MusicInfo info) { w.lock(); try { mMp3List.add(info); if (mAdapter != null) mAdapter.notifyDataSetChanged(); } finally { w.unlock(); } } public void append(ArrayList<MusicInfo> mp3List) { w.lock(); try { mMp3List.addAll(mp3List); mAdapter.notifyDataSetChanged(); } finally { w.unlock(); } } public int size() { r.lock(); try { return mMp3List.size(); } finally { r.unlock(); } } public MusicInfo get(int i) { r.lock(); try { return mMp3List.get(i); } finally { r.unlock(); } } } private final class Mp3ListAdapter extends BaseAdapter { private final static int VIEW_TYPE_NORMAL = 0; private final static int VIEW_TYPE_FOOTER = 1; private int mResource; private LayoutInflater mInflater; private ListStatusView.Status mStatus; public Mp3ListAdapter(Context context, int resource) { mResource = resource; mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); } @Override public int getCount() { boolean showFooter = (mStatus == ListStatusView.Status.ERROR || mStatus == ListStatusView.Status.LOADING) && mKeepFetching; int footerCount = showFooter ? 1 : 0; if (mData == null) return footerCount; return mData.size() + footerCount; } @Override public Object getItem(int position) { if (mData == null) return null; if (position <mData.size()) return mData.get(position); return null; // footer. } @Override public long getItemId(int position) { if (mData == null) return -1; if (position < mData.size()) return position; return -1; // footer. } @Override public int getViewTypeCount() { return 2; } @Override public int getItemViewType(int position) { if (mData == null || position == mData.size()) { return VIEW_TYPE_FOOTER; } return VIEW_TYPE_NORMAL; } @Override public View getView(int position, View convertView, ViewGroup parent) { boolean isFooter = (mData == null || position == mData.size()) && mKeepFetching; if (isFooter) { ListStatusView footerView = (ListStatusView) convertView; if (footerView == null) { footerView = (ListStatusView) mInflater.inflate(R.layout.liststatus, null); TextView text = (TextView)footerView.findViewById(R.id.prompt); text.setText(R.string.loading_more); } if (mStatus == ListStatusView.Status.LOADING) { footerView.setLoadingStatus(); } else if (mStatus == ListStatusView.Status.ERROR) { footerView.setErrorStatus(new RetryLoadingClickListener()); } return footerView; } if (position==mData.size()-1 && mStatus!=Status.LOADED && mKeepFetching) { mHandler.post(new Runnable() { @Override public void run() { continueFetch(mSearchKey, true); } }); } ViewHolder holder = new ViewHolder(); Object item = mData.get(position); if (convertView == null) { convertView = mInflater.inflate(mResource, parent, false); holder.image = ((ImageView)convertView.findViewById(R.id.image)); holder.title = ((TextView)convertView.findViewById(R.id.title)); holder.artist = ((TextView)convertView.findViewById(R.id.artist)); holder.downloadCount = ((TextView)convertView.findViewById(R.id.download_count)); holder.rating = ((RatingBar)convertView.findViewById(R.id.ratebar_indicator)); convertView.setTag(holder); } else { holder = (ViewHolder)convertView.getTag(); } MusicInfo info = (MusicInfo) item; com.cinla.imageloader.ImageLoader.initialize(SearchListActivity.this); com.cinla.imageloader.ImageLoader.start(info.getmImageUrl(), holder.image); holder.title.setText(info.getmTitle()); holder.artist.setText(info.getmArtist()); holder.downloadCount.setText(getString(R.string.download_count)+" "+Integer.toString(info.getmDownloadCount())); holder.rating.setRating((float)info.getmRate()/20); return convertView; } protected void setStatus(ListStatusView.Status status) { mStatus = status; } } private static class ViewHolder { ImageView image; TextView title; TextView artist; TextView downloadCount; RatingBar rating; } public class FetchMp3ListTask extends AsyncTask<String, Void, ArrayList<MusicInfo>> { private int mStartPosTemp; private boolean mIsNext; public FetchMp3ListTask(boolean isNext) { mIsNext = isNext; } @Override protected void onPreExecute() { super.onPreExecute(); setLoadingStatus(); mStartPosTemp = mStartPos; if (mAdapter != null) { mAdapter.setStatus(com.cinla.ringtone.ListStatusView.Status.LOADING); } // if (mData != null) { // mData.clear(); // } } @Override protected ArrayList<MusicInfo> doInBackground(String... params) { // Utils.D(params[0]); ArrayList<MusicInfo> results = null; if (mIsNext) { results = getNextMp3List(params[0]); } else { results = getPrevMp3List(params[0]); } return results; } @Override protected void onPostExecute(ArrayList<MusicInfo> result) { super.onPostExecute(result); if ((mData!=null && mData.size()==0)||mData==null) { if (result == null) { setErrorStatus(); return; } if (result.size() == 0) { setNoResultStatus(); return; } } else { if (result == null) { mAdapter.setStatus(com.cinla.ringtone.ListStatusView.Status.ERROR); mAdapter.notifyDataSetChanged(); } } SearchListActivity.this.handleSearchResults(result); if (result!=null && result.size()>0) { mStartPosTemp += result.size(); mStartPos = mStartPosTemp; } } private ArrayList<MusicInfo> getNextMp3List(String keyWord) { ArrayList<MusicInfo> results = null; if (mSearchType==Constant.TYPE_KEY || mSearchType==Constant.TYPE_EMPTY) { Utils.D("Position: "+mStartPosTemp); results = mFetcher.getMusicListByQueryKey(keyWord, mStartPosTemp); } else if (mSearchType == Constant.TYPE_ARTIST) { results = mFetcher.getMusicListByArtist(keyWord, mStartPosTemp); } else if (mSearchType == Constant.TYPE_CATEGORY) { results = mFetcher.getMusicListByCategory(keyWord, mStartPosTemp); } else if (mSearchType == Constant.TYPE_NEWEST) { results = mFetcher.getMusicListByAddDate(mStartPosTemp); } else if (mSearchType == Constant.TYPE_TOP_DOWNLOAD) { results = mFetcher.getMusicListByDownloadCount(mStartPosTemp); } if (results!=null && results.size()>=0 && results.size()<Constant.EACH_MAX_RESULTS_NUM) { mKeepFetching = false; } return results; } private ArrayList<MusicInfo> getPrevMp3List(String keyWord) { mStartPosTemp -= Constant.EACH_MAX_RESULTS_NUM; if (mStartPosTemp < 0) { mStartPosTemp = 0; } ArrayList<MusicInfo> results = null; if (mSearchType==Constant.TYPE_KEY || mSearchType==Constant.TYPE_EMPTY) { results = mFetcher.getMusicListByQueryKey(keyWord, mStartPosTemp); } else if (mSearchType == Constant.TYPE_ARTIST) { results = mFetcher.getMusicListByArtist(keyWord, mStartPosTemp); } else if (mSearchType == Constant.TYPE_CATEGORY) { results = mFetcher.getMusicListByCategory(keyWord, mStartPosTemp); } else if (mSearchType == Constant.TYPE_NEWEST) { results = mFetcher.getMusicListByAddDate(mStartPosTemp); } else if (mSearchType == Constant.TYPE_TOP_DOWNLOAD) { results = mFetcher.getMusicListByDownloadCount(mStartPosTemp); } return results; } } private void setLoadingStatus() { mProgressBar.setVisibility(View.VISIBLE); mRetryButton.setVisibility(View.GONE); mSearchMessage.setVisibility(View.VISIBLE); mSearchMessage.setText(SearchListActivity.this.getString(R.string.please_wait_search)); } private void setErrorStatus() { mProgressBar.setVisibility(View.GONE); mRetryButton.setVisibility(View.VISIBLE); mSearchMessage.setText(R.string.load_error_message); mSearchMessage.setVisibility(View.VISIBLE); } private void setHintStatus() { mProgressBar.setVisibility(View.GONE); mRetryButton.setVisibility(View.GONE); mSearchMessage.setVisibility(View.VISIBLE); mSearchMessage.setText(R.string.search_hint_message); } private void setNoResultStatus() { mProgressBar.setVisibility(View.GONE); mRetryButton.setVisibility(View.GONE); mSearchMessage.setVisibility(View.VISIBLE); mSearchMessage.setText(R.string.no_result); } private class RetryButtonClickListener implements View.OnClickListener { @Override public void onClick(View v) { SearchListActivity.this.startQuery(mSearchKey.trim()); } } private class RetryLoadingClickListener implements View.OnClickListener { @Override public void onClick(View v) { mAdapter.setStatus(Status.LOADING); mAdapter.notifyDataSetChanged(); continueFetch(mSearchKey, true); } } private class PrevButtonClickListener implements View.OnClickListener { @Override public void onClick(View v) { continueFetch(mSearchKey, false); } } private class NextButtonClickListener implements View.OnClickListener { @Override public void onClick(View v) { continueFetch(mSearchKey, true); } } public static void startQeuryByKey(Context context, String keyWord) { Intent intent = new Intent(context, SearchListActivity.class); intent.putExtra(Constant.SEARCH_TYPE, Constant.TYPE_KEY); intent.putExtra(Constant.QUERY, keyWord); context.startActivity(intent); } public static void startQeuryByKey(Context context, String keyWord, boolean isHideSearchBar) { Intent intent = new Intent(context, SearchListActivity.class); intent.putExtra(Constant.SEARCH_TYPE, Constant.TYPE_KEY); intent.putExtra(Constant.QUERY, keyWord); intent.putExtra(Constant.HIDE_SEARCHBAR, isHideSearchBar); context.startActivity(intent); } public static void startQueryByCategory(Context context, String keyWord) { Intent intent = new Intent(context, SearchListActivity.class); intent.putExtra(Constant.SEARCH_TYPE, Constant.TYPE_CATEGORY); intent.putExtra(Constant.QUERY, keyWord); context.startActivity(intent); } public static void startQueryByArtist(Context context, String keyWord) { Intent intent = new Intent(context, SearchListActivity.class); intent.putExtra(Constant.SEARCH_TYPE, Constant.TYPE_ARTIST); intent.putExtra(Constant.QUERY, keyWord); context.startActivity(intent); } public static void startQueryByDownloadcount(Context context) { Intent intent = new Intent(context, SearchListActivity.class); intent.putExtra(Constant.SEARCH_TYPE, Constant.TYPE_TOP_DOWNLOAD); intent.putExtra(Constant.QUERY, ""); context.startActivity(intent); } public static void startQueryByDate(Context context) { Intent intent = new Intent(context, SearchListActivity.class); intent.putExtra(Constant.SEARCH_TYPE, Constant.TYPE_NEWEST); intent.putExtra(Constant.QUERY, ""); context.startActivity(intent); } }