package de.tum.in.tumcampusapp.activities.generic;
import android.app.SearchManager;
import android.app.SearchableInfo;
import android.content.Context;
import android.content.Intent;
import android.content.SearchRecentSuggestionsProvider;
import android.database.Cursor;
import android.provider.SearchRecentSuggestions;
import android.support.v4.view.MenuItemCompat;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.SearchView;
import android.view.Menu;
import android.view.MenuItem;
import de.tum.in.tumcampusapp.R;
import de.tum.in.tumcampusapp.auxiliary.Utils;
/**
* Generic class for searching. Provides basic functions for a {@link SearchView}
* and typical processes related to search.
*/
public abstract class ActivityForSearching extends ProgressActivity {
/**
* Search authority and minimum query length
*/
private final String mAuthority;
private final int mMinLength;
/**
* Last search query
*/
protected String mQuery;
/**
* SearchView handle
*/
private SearchView mSearchView;
private MenuItem mSearchItem;
/**
* @see ActivityForSearching#openSearch()
*/
private boolean mOpenSearch;
/**
* Initializes an activity for searching.
* The xml layout must include an error_layout and a progress_layout.
* A {@link SwipeRefreshLayout}
* called ptr_layout is required if the activity should support PullToRefresh method
*
* @param layoutId Resource id of the xml layout that should be used to inflate the activity
* @param auth Authority for search suggestions declared in manifest file
* @param minLen Minimum text length that has to be entered by the user before a search quest can be submitted
*/
public ActivityForSearching(int layoutId, String auth, int minLen) {
super(layoutId);
mAuthority = auth;
mMinLength = minLen;
}
/**
* Gets called if search has been canceled
*/
protected abstract void onStartSearch();
/**
* Gets called if a search query has been entered
*
* @param query Query to search for
*/
protected abstract void onStartSearch(String query);
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
// Inflate the menu; this adds a SearchView to the ActionBar
getMenuInflater().inflate(R.menu.menu_search, menu);
// Get SearchView
mSearchItem = menu.findItem(R.id.action_search);
mSearchView = (SearchView) MenuItemCompat.getActionView(mSearchItem);
// Set the searchable configuration
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
SearchableInfo info = searchManager.getSearchableInfo(getComponentName());
mSearchView.setSearchableInfo(info);
// If activity gets called via Intent with a search query set SearchView accordingly
if (mQuery != null) {
mSearchView.setQuery(mQuery, false);
}
// Ensures that SearchView is updated if suggestion has been clicked
mSearchView.setOnSuggestionListener(new SearchView.OnSuggestionListener() {
@Override
public boolean onSuggestionSelect(int i) {
return false;
}
@Override
public boolean onSuggestionClick(int position) {
String suggestion = getSuggestion(position);
mSearchView.setQuery(suggestion, true);
return true;
}
private String getSuggestion(int position) {
Cursor cursor = (Cursor) mSearchView.getSuggestionsAdapter().getItem(position);
return cursor.getString(cursor.getColumnIndex(SearchManager.SUGGEST_COLUMN_TEXT_1));
}
});
// Handle search cancellation
mSearchView.setOnCloseListener(new SearchView.OnCloseListener() {
@Override
public boolean onClose() {
MenuItemCompat.collapseActionView(mSearchItem);
mQuery = null;
onStartSearch();
return false;
}
});
MenuItemCompat.setOnActionExpandListener(mSearchItem, new MenuItemCompat.OnActionExpandListener() {
@Override
public boolean onMenuItemActionExpand(MenuItem item) {
return true;
}
@Override
public boolean onMenuItemActionCollapse(MenuItem item) {
mQuery = null;
onStartSearch();
return true;
}
});
return true;
}
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
if (mOpenSearch) {
MenuItemCompat.setShowAsAction(mSearchItem, MenuItemCompat.SHOW_AS_ACTION_ALWAYS | MenuItemCompat.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW);
MenuItemCompat.expandActionView(mSearchItem);
return true;
}
return super.onPrepareOptionsMenu(menu);
}
@Override
public void onNewIntent(Intent intent) {
super.onNewIntent(intent);
if (intent == null) {
return;
}
setIntent(intent);
if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
requestSearch(intent.getStringExtra(SearchManager.QUERY));
}
}
/**
* Tests if search query is valid and internet connection is available.
* Then starts a new search.
*
* @param query Query to search for
*/
protected void requestSearch(String query) {
mQuery = query;
if (query.length() < mMinLength) {
final String text = String.format(getString(R.string.min_search_len), mMinLength);
Utils.showToast(this, text);
return;
}
/*if (!Utils.isConnected(this)) {
showNoInternetLayout();
return;
}*/
// Add query to recents
SearchRecentSuggestions suggestions = new SearchRecentSuggestions(this, mAuthority, SearchRecentSuggestionsProvider.DATABASE_MODE_QUERIES);
suggestions.saveRecentQuery(query, null);
// Tell activity to start searching
onStartSearch(query);
}
/**
* Expands the Search-ActionView on activity startup, so that the user can immediately start typing.
* Only has an effect if it is called during
* {@link de.tum.in.tumcampusapp.activities.generic.ActivityForSearching#onCreate(android.os.Bundle)}} or
* {@link de.tum.in.tumcampusapp.activities.generic.ActivityForSearching#onResume()}} method.
*/
protected void openSearch() {
mOpenSearch = true;
}
@Override
public void onRefresh() {
requestSearch(mQuery);
}
}