package org.goodev.discourse;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.NavUtils;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.RadioGroup.OnCheckedChangeListener;
import android.widget.SearchView;
import android.widget.SearchView.OnQueryTextListener;
import android.widget.TextView;
import org.goodev.discourse.api.Api;
import org.goodev.discourse.api.SearchTask;
import org.goodev.discourse.api.data.SearchTopic;
import org.goodev.discourse.api.data.SearchUser;
import org.goodev.discourse.utils.ImageLoader;
import org.goodev.discourse.utils.L;
import org.goodev.discourse.utils.Utils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
public class SearchActivity extends FragmentActivity implements OnQueryTextListener, OnCheckedChangeListener, OnItemClickListener {
public static final String KEY_SEARCH_QUERY = "query_text";
private ListView mListView;
private RadioButton mTopicsBtn;
private RadioButton mUsersBtn;
private RadioGroup mRadioGroup;
private TopicsAdapter mTopicsAdapter;
private UsersAdapter mUsersAdapter;
private String mQuery;
private String mPreUserQuery;
private String mPreTopicQuery;
private View mEmptyView;
private View mLoadingView;
private LayoutInflater mLayoutInflater;
private SearchTopicsTask mTopicsTask;
private SearchUsersTask mUsersTask;
private ArrayList<SearchUser> mUsers = new ArrayList<SearchUser>();
private ArrayList<SearchTopic> mTopics = new ArrayList<SearchTopic>();
private ImageLoader mImageLoader;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
setContentView(R.layout.activity_search);
mImageLoader = App.getImageLoader(this, getResources());
mLayoutInflater = LayoutInflater.from(this);
if (savedInstanceState != null) {
mQuery = savedInstanceState.getString(KEY_SEARCH_QUERY, null);
}
// Show the Up button in the action bar.
setupActionBar();
setupViews();
}
/**
* Set up the {@link android.app.ActionBar}.
*/
private void setupActionBar() {
getActionBar().setDisplayHomeAsUpEnabled(true);
}
private void setupViews() {
mLoadingView = findViewById(R.id.loading_layout);
mUsersAdapter = new UsersAdapter();
mTopicsAdapter = new TopicsAdapter();
mRadioGroup = (RadioGroup) findViewById(R.id.radio_group);
mListView = (ListView) findViewById(android.R.id.list);
mEmptyView = findViewById(android.R.id.empty);
mListView.setEmptyView(mEmptyView);
mListView.setAdapter(mTopicsAdapter);
mListView.setOnItemClickListener(this);
mUsersBtn = (RadioButton) findViewById(R.id.users_btn);
mTopicsBtn = (RadioButton) findViewById(R.id.topics_btn);
mRadioGroup.setOnCheckedChangeListener(this);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.search, menu);
MenuItem search = menu.findItem(R.id.action_search);
SearchView searchView = (SearchView) search.getActionView();
searchView.setQueryHint(getString(R.string.search_hint));
searchView.setOnQueryTextListener(this);
searchView.setIconifiedByDefault(false);
if (mQuery != null) {
searchView.setQuery(mQuery, false);
}
// Associate searchable configuration with the SearchView
// SearchManager searchManager =
// (SearchManager) getSystemService(Context.SEARCH_SERVICE);
// searchView.setSearchableInfo(
// searchManager.getSearchableInfo(getComponentName()));
return true;
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString(KEY_SEARCH_QUERY, mQuery);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
// This ID represents the Home or Up button. In the case of this
// activity, the Up button is shown. Use NavUtils to allow users
// to navigate up one level in the application structure. For
// more details, see the Navigation pattern on Android Design:
//
// http://developer.android.com/design/patterns/navigation.html#up-vs-back
//
NavUtils.navigateUpFromSameTask(this);
case R.id.action_search:
L.i();
return false;
}
return super.onOptionsItemSelected(item);
}
@Override
public boolean onQueryTextChange(String newText) {
L.i(newText);
return false;
}
@Override
public boolean onQueryTextSubmit(String query) {
L.i(query);
mQuery = query;
startSearch();
return false;
}
/**
* TODO 缓存搜索结果,当mQuery 没有变化的时候 不再重新请求数据。。。。
*/
private void startSearch() {
if (mUsersBtn.isChecked()) {
if (mQuery != null && mQuery.equals(mPreUserQuery) && mUsers.size() > 0) {
mListView.setAdapter(mUsersAdapter);
return;
}
searchStart();
mPreUserQuery = null;
mUsers.clear();
mListView.setAdapter(mUsersAdapter);
searchUsers(mQuery);
} else if (mTopicsBtn.isChecked()) {
if (mQuery != null && mQuery.equals(mPreTopicQuery) && mTopics.size() > 0) {
mListView.setAdapter(mTopicsAdapter);
return;
}
searchStart();
mPreTopicQuery = null;
mTopics.clear();
mListView.setAdapter(mTopicsAdapter);
searchTopics(mQuery);
}
}
private void searchTopics(String query) {
if (mTopicsTask != null) {
mTopicsTask.cancel(true);
}
mTopicsTask = new SearchTopicsTask();
mTopicsTask.execute(String.format(Api.SEARCH_TOPIC, query));
}
private void searchUsers(String query) {
if (mUsersTask != null) {
mUsersTask.cancel(true);
}
mUsersTask = new SearchUsersTask();
mUsersTask.execute(String.format(Api.SEARCH_USER, query));
}
void searchStart() {
mListView.setEmptyView(mLoadingView);
mEmptyView.setVisibility(View.INVISIBLE);
// mListView.setVisibility(View.INVISIBLE);
// mLoadingView.setVisibility(View.VISIBLE);
}
void searchFinished() {
mListView.setEmptyView(mEmptyView);
mLoadingView.setVisibility(View.INVISIBLE);
}
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
if (TextUtils.isEmpty(mQuery)) {
return;
}
startSearch();
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Object item = parent.getItemAtPosition(position);
if (item instanceof SearchUser) {
openUserActivity((SearchUser) item);
} else if (item instanceof SearchTopic) {
openTopicActivity((SearchTopic) item);
}
}
private void openTopicActivity(SearchTopic item) {
if (item.url != null && item.url.startsWith("/t")) {
String[] paths = item.url.split("/");
ActivityUtils.startTopicActivity(this, paths[2], paths[3]);
} else {
L.e("open search topics error:%s ", item.url);
}
}
private void openUserActivity(SearchUser item) {
ActivityUtils.openUserActivity(this, item.id);
}
class UsersAdapter extends BaseAdapter {
@Override
public int getCount() {
return mUsers.size();
}
@Override
public Object getItem(int position) {
return mUsers.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = mLayoutInflater.inflate(R.layout.search_user_item, parent, false);
}
ImageView iv = (ImageView) convertView.findViewById(R.id.icon);
TextView name = (TextView) convertView.findViewById(R.id.name);
SearchUser user = (SearchUser) getItem(position);
name.setText(user.title);
mImageLoader.get(Utils.getAvatarUrl(user.avatar_template, Api.AVATAR_SIZE_BIG), iv);
return convertView;
}
public void setData(ArrayList<SearchUser> result) {
mUsers.clear();
mUsers.addAll(result);
notifyDataSetChanged();
}
}
class TopicsAdapter extends BaseAdapter {
@Override
public int getCount() {
return mTopics.size();
}
@Override
public Object getItem(int position) {
return mTopics.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
TextView v;
if (convertView == null) {
v = (TextView) mLayoutInflater.inflate(android.R.layout.simple_list_item_1, parent, false);
} else {
v = (TextView) convertView;
}
SearchTopic topic = (SearchTopic) getItem(position);
v.setText(topic.title);
return v;
}
public void setData(ArrayList<SearchTopic> result) {
mTopics.clear();
mTopics.addAll(result);
notifyDataSetChanged();
}
}
class SearchTopicsTask extends SearchTask<ArrayList<SearchTopic>> {
@Override
public ArrayList<SearchTopic> parse(String body) {
ArrayList<SearchTopic> topics = new ArrayList<SearchTopic>();
try {
JSONArray array = new JSONArray(body);
if (array.length() == 0) {
return null;
}
JSONObject obj = array.getJSONObject(0);
if (Api.TYPE_TOPIC.equals(obj.getString(Api.TYPE))) {
JSONArray results = obj.getJSONArray(Api.RESULTS);
int length = results.length();
for (int i = 0; i < length; i++) {
JSONObject o = results.getJSONObject(i);
SearchTopic topic = Api.getJSONObject(o, SearchTopic.class);
topics.add(topic);
}
return topics;
}
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
setProgressBarIndeterminateVisibility(true);
}
@Override
protected void onPostExecute(ArrayList<SearchTopic> result) {
super.onPostExecute(result);
setProgressBarIndeterminateVisibility(false);
searchFinished();
if (mTopicsTask != this) {
return;
}
if (result != null) {
mTopicsAdapter.setData(result);
}
mPreTopicQuery = mQuery;
mListView.setAdapter(mTopicsAdapter);
}
}
class SearchUsersTask extends SearchTask<ArrayList<SearchUser>> {
@Override
protected void onPreExecute() {
super.onPreExecute();
setProgressBarIndeterminateVisibility(true);
}
@Override
protected void onPostExecute(ArrayList<SearchUser> result) {
super.onPostExecute(result);
setProgressBarIndeterminateVisibility(false);
searchFinished();
if (mUsersTask != this) {
return;
}
if (result != null) {
mUsersAdapter.setData(result);
}
mPreUserQuery = mQuery;
mListView.setAdapter(mUsersAdapter);
}
@Override
public ArrayList<SearchUser> parse(String body) {
ArrayList<SearchUser> users = new ArrayList<SearchUser>();
try {
JSONArray array = new JSONArray(body);
if (array.length() == 0) {
return null;
}
JSONObject obj = array.getJSONObject(0);
if (Api.TYPE_USER.equals(obj.getString(Api.TYPE))) {
JSONArray results = obj.getJSONArray(Api.RESULTS);
int length = results.length();
for (int i = 0; i < length; i++) {
JSONObject o = results.getJSONObject(i);
SearchUser user = Api.getJSONObject(o, SearchUser.class);
users.add(user);
}
return users;
}
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
}
}