L'Action Bar non è semplicemente un elemento estetico dell'interfaccia. Il suo ruolo di pattern applicativo è stato sempre messo in luce dal team Android. Oltre a contenere action e dare fondamento alla struttura a tab, l'Action Bar può ospitare diversi widget, il più comune dei quali è il Search Widget.
Come si vede, un Search Widget viene denotato da una comune icona nella Action Bar, tipicamente l'immagine di una lente di ingrandimento. Selezionandola, appare un campo di testo che permette l'inserimento dei termini da utilizzare come query di ricerca, per selezionare contenuti dell'app.
Per includere un Search Widget nell'Action Bar, si ha bisogno di alcuni elementi da configurare all'interno dell'applicazione.
Per prima cosa, è necessario aggiungere l'action relativa, e lo faremo nella stessa maniera in cui trattiamo gli Options Menu.
Creiamo il file /res/menu/main.xml:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:id="@+id/action_search"
android:icon="@android:drawable/ic_menu_search"
android:title="@string/action_search"
app:showAsAction="always"
app:actionViewClass="android.support.v7.widget.SearchView"/>
</menu>
L'aspetto più importante da rilevare è la presenza di un attributo actionViewClass
, in cui si specifica che il widget da includere è definito nella classe SearchView
.
Come icona è stata utilizzata una risorsa di sistema, ic_menu_search
, in modo che possa risultare subito familiare all'utente.
Un secondo elemento, sempre definito in XML, è la configurazione del componente, specificata nel file /res/xml/searcable.xml:
<?xml version="1.0" encoding="utf-8"?>
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
android:hint="@string/search_hint"
android:label="@string/app_name" />
L'attributo hint
fa riferimento ad una stringa definita tra le risorse, contenente la frase che fornisce il suggerimento per l'utente all'atto della ricerca.
Affinchè il Search Widget appaia nella Action Bar, il layout che lo contiene deve essere caricato dall'Activity mediante il metodo onCreateOptionsMenu
. Si tratta del terzo passo da compiere:
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main, menu);
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
SearchView searchView = (SearchView) menu.findItem(R.id.action_search)
.getActionView();
searchView.setSearchableInfo(searchManager
.getSearchableInfo(getComponentName()));
return true;
}
Il codice Java appena esposto dapprima richiama il file /res/menu/main.xml e lo utilizza per popolare l'Action Bar, successivamente configura il componente SearchView
.
Questo metodo è l'unico che dovremo aggiungere all'Activity. Non sarà necessario gestire la selezione dell'action, come si fa comunemente, tramite l'override di onOptionsItemSelected
.
Il widget serve essenzialmente a raccogliere una query che formalizza la richiesta di dati.
Tale stringa sarà inviata ad un'Activity di ricerca, che si occuperà di trovare le informazioni corrispondenti ai parametri, e di mostrare i risultati.
L'Activity verrà attivata da un Intent
contenente i dati della ricerca tra gli Extra di tipo String
, e contraddistinto da un tipo di azione ACTION_SEARCH
.
Tale Activity, schematicamente, ha bisogno di alcuni elementi per funzionare:
public class SearchActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search);
ActionBar actionBar = getActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
handleIntent(getIntent());
}
@Override
protected void onNewIntent(Intent intent) {
setIntent(intent);
handleIntent(intent);
}
private void handleIntent(Intent intent) {
if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
String query = intent.getStringExtra(SearchManager.QUERY);
/*
* codice che utilizza il contenuto dell'oggetto
* String query per effettuare la ricerca
*/
}
}
}
Nel metodo onCreate
, oltre all'inserimento di un layout che mostri i risultati della ricerca, viene gestito l'Intent
di attivazione e passato al metodo handleIntent
. Al suo interno, per prima cosa ci si accerta che l'Intent
risponda ad un ACTION_SEARCH
e, solo in questo caso, si estrae la stringa di ricerca. Tutto il codice occorrente ad ottenere i risultati può essere collocato dove ora appare il commento, e dipenderà dal modo in cui l'app gestisce i dati (database, strutture dati, accesso remoto o altro).
L'ultimo passo è la configurazione del manifest. Apriamo il file AndroidManifest.xml ed apportiamo le seguenti modifiche all'interno del nodo <application>
:
-
dichiariamo l'Activity di ricerca con il corretto
IntentFilter
ed i metadati che rimandano alla configurazione XML:
<activity android:name=".SearchActivity" android:parentActivityName=".MainActivity" > <intent-filter> <action android:name="android.intent.action.SEARCH" /> </intent-filter> <meta-data android:name="android.app.searchable" android:resource="@xml/searchable" /> </activity>
-
inseriamo ulteriori metadati che specificano qual è l'Activity di ricerca di default:
<meta-data android:name="android.app.default_searchable" android:value=".SearchActivity" />
La versione completa del codice sopra descritto è allegata a questa lezione.