blob: 07c7bd1c66e368a6fe1ed97423def799fbfb7553 [file] [log] [blame]
/*
* Copyright (C) 2014 Google Inc.
* Licensed to The Android Open Source Project.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.mail.ui;
import android.app.SearchManager;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.AsyncTask;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import com.android.mail.R;
import com.android.mail.providers.SearchRecentSuggestionsProvider;
import com.google.common.collect.Lists;
import java.util.List;
/**
* Custom quantum-styled search view that overlays the main activity.
*/
public class MaterialSearchSuggestionsList extends LinearLayout
implements AdapterView.OnItemClickListener, View.OnClickListener {
private MaterialSearchViewController mController;
private SearchRecentSuggestionsProvider mSuggestionsProvider;
private List<SuggestionItem> mSuggestions = Lists.newArrayList();
private String mQuery;
private MaterialSearchViewListAdapter mAdapter;
private QuerySuggestionsTask mQueryTask;
public MaterialSearchSuggestionsList(Context context) {
super(context);
}
public MaterialSearchSuggestionsList(Context context, AttributeSet attrs) {
super(context, attrs);
}
// PUBLIC API
public void setController(MaterialSearchViewController controller,
SearchRecentSuggestionsProvider suggestionsProvider) {
mController = controller;
mSuggestionsProvider = suggestionsProvider;
}
public void setQuery(String query) {
mQuery = query;
if (mQueryTask != null) {
mQueryTask.cancel(true);
}
mQueryTask = new QuerySuggestionsTask();
mQueryTask.execute(query);
}
// PRIVATE API
@Override
protected void onFinishInflate() {
super.onFinishInflate();
final ListView listView = (ListView) findViewById(R.id.search_overlay_suggestion_list);
listView.setOnItemClickListener(this);
final View dummyHolder = findViewById(R.id.search_overlay_scrim);
dummyHolder.setOnClickListener(this);
// set up the adapter
mAdapter = new MaterialSearchViewListAdapter(getContext(), R.layout.search_suggestion_item);
listView.setAdapter(mAdapter);
}
@Override
public void setVisibility(int visibility) {
if (!isShown() && visibility == VISIBLE) {
// When we go from gone to visible, re-query for suggestions in case they changed.
setQuery(mQuery);
}
super.setVisibility(visibility);
}
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
mController.onSearchPerformed(mSuggestions.get(position).suggestion);
}
@Override
public void onClick(View view) {
mController.setQueryText(mController.getKeyWord());
if (mController.isQueryTextNull()) {
mController.focusSearchBar(false);
} else if (mController.ismIsShowEmptyView()) {
mController.showSearchActionBar(
MaterialSearchViewController.SEARCH_VIEW_STATE_VISIBLE);
mController.focusSearchBar(false);
} else {
mController.showSearchActionBar(
MaterialSearchViewController.SEARCH_VIEW_STATE_ONLY_ACTIONBAR);
}
}
// Background task for querying the suggestions list
private class QuerySuggestionsTask extends AsyncTask<String, Void, List<SuggestionItem>> {
@Override
protected List<SuggestionItem> doInBackground(String... strings) {
String query = strings[0];
if (query == null) {
query = "";
}
Cursor c = null;
final List<SuggestionItem> result = Lists.newArrayList();
try {
c = mSuggestionsProvider.query(query);
if (c != null && c.moveToFirst()) {
final int textIndex = c.getColumnIndex(SearchManager.SUGGEST_COLUMN_QUERY);
final int iconIndex = c.getColumnIndex(SearchManager.SUGGEST_COLUMN_ICON_1);
do {
final String suggestion = c.getString(textIndex);
final Uri iconUri = Uri.parse(c.getString(iconIndex));
result.add(new SuggestionItem(suggestion, iconUri));
} while (c.moveToNext());
}
} catch (IllegalStateException e) {
// db could have been closed due to cleanup, simply don't do anything.
} finally {
if (c != null) {
c.close();
}
}
return result;
}
@Override
protected void onPostExecute(List<SuggestionItem> strings) {
if (!isCancelled()) {
// Should not have any race conditions here since we cancel the previous asynctask
// before starting the new one. It's unlikely that the new task finishes fast enough
// to get to onPostExecute when this one is in addAll.
mSuggestions.clear();
mSuggestions.addAll(strings);
mAdapter.notifyDataSetChanged();
}
}
}
private static class SuggestionItem {
final String suggestion;
final Uri icon;
public SuggestionItem(String s, Uri i) {
suggestion = s;
icon = i;
}
}
// Custom adapter to populate our list
private class MaterialSearchViewListAdapter extends BaseAdapter {
private final Context mContext;
private final int mResId;
private LayoutInflater mInflater;
public MaterialSearchViewListAdapter(Context context, int resource) {
super();
mContext = context;
mResId = resource;
}
private LayoutInflater getInflater() {
if (mInflater == null) {
mInflater = LayoutInflater.from(mContext);
}
return mInflater;
}
@Override
public int getCount() {
return mSuggestions.size();
}
@Override
public Object getItem(int i) {
return mSuggestions.get(i);
}
@Override
public long getItemId(int i) {
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = getInflater().inflate(mResId, parent, false);
}
final SuggestionItem item = mSuggestions.get(position);
final TextView text =
(TextView) convertView.findViewById(R.id.search_overlay_item_text);
text.setText(item.suggestion);
text.setContentDescription(getResources().getString(R.string.search_suggestion_desc,
item.suggestion));
((ImageView) convertView.findViewById(R.id.search_overlay_item_icon))
.setImageURI(item.icon);
return convertView;
}
}
}