20

Attualmente ho la mia applicazione impostata con un ListFragment a sinistra e un DetailsFragment a destra (simile al layout sul tablet in basso).Barra delle applicazioni Android Implementazione del widget di ricerca in ListFragment

layout

Nella barra di azione Ho un widget di ricerca che al momento della presentazione di un termine di ricerca dovrebbe aggiornare i contenuti della lista (nel ListFragment). Ho seguito la guida di ricerca su android dev (http://developer.android.com/guide/topics/search/search-dialog.html) ma sto riscontrando problemi nel trovare la ricerca per aggiornare l'elenco nella stessa attività.

Sono riuscito a far funzionare una qualche forma di implementazione chiamando una nuova attività quando viene inviato il termine di ricerca ma questo fa sì che il pulsante Indietro si comporti in modo strano (cioè si preme indietro e si passa all'attività precedente con il widget di ricerca ancora visualizzazione del termine di ricerca).

ho aggiunto le linee di intenti per il manifesto come segue

<intent-filter> 
     <action android:name="android.intent.action.SEARCH" /> 
    </intent-filter> 
    <meta-data android:name="android.app.searchable" 
       android:resource="@xml/searchable"/> 

E 'possibile ottenere il widget di ricerca per aggiornare l'elenco delle attività in corso?

risposta

46

Sì, in effetti, è il caso d'uso "normale". Quello che devi ricordare è che il frammento che usa il widget della barra delle azioni di ricerca, dovrebbe essere la parte che lo registra in generale, poiché il widget verrà distrutto insieme a quel frammento.

Ecco come legare correttamente in su:

nel vostro ListFragment fatto sapere che si dispone di elementi di menu di opzione ...

@Override 
public void onActivityCreated(Bundle savedInstanceState) { 
    .. 
    setHasOptionsMenu(true); 
    .. 
} 

poi dentro lo stesso ListFragment creare il menu delle opzioni sovrascrivendo la richiamata, una volta che hai il riferimento widget di SearchView, registrare un callback QueryTextListener:

@Override 
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { 
    inflater.inflate(R.menu.grid_default, menu); 
    SearchView searchView = (SearchView)menu.findItem(R.id.grid_default_search).getActionView(); 
    searchView.setOnQueryTextListener(queryListener); 
} 

creare le s earch widget di via o di programmazione (Java) o dichiarativo (XML) qui è XML (chiamato grid_default.xml, dall'alto):

<?xml version="1.0" encoding="utf-8"?> 
<menu xmlns:android="http://schemas.android.com/apk/res/android"> 

    <item  
     android:id="@+id/grid_default_search" 
     android:icon="@android:drawable/ic_menu_search" 
     android:title="search" 
     android:showAsAction="always" 
     android:actionViewClass="android.widget.SearchView" 
    /> 

    <!-- other items or whatever --> 

</menu> 

ora indietro nella vostra ListFragment è necessario creare il queryListener abbiamo registrato in precedenza:

ora sai quando una query viene modificata o inoltrata, nel mio esempio, richiudo ogni volta che viene premuto un tasto perché il mio database era piccolo e veloce con i risultati, potresti dover cambiare questo .. ma tu " noterò come sto usando il widget per impostare un campo di classe privata all'interno dello ListFragment al testo corrente del sear widget di ch (grid_currentQuery) e poi io sono solo chiamando getLoaderManager().restartLoader(0, null, MyListFragment.this); dove dentro la mia onCreateLoader sto solo aggiornando la domanda che ho usato in questo modo:

@Override 
public Loader<Cursor> onCreateLoader(int id, Bundle bargs) { 

    String sort = "SortColumn ASC"; 
    String[] grid_columns = new String[] { "ColumnA", "ColumnB", "Etc..." }; 
    String grid_whereClause = "ColumnToSearchBy LIKE ?" 

    if (!TextUtils.isEmpty(grid_currentQuery)) {    
     return new CursorLoader(getActivity(), DataProvider.CONTENT_URI, grid_columns, grid_whereClause, new String[] { grid_currentQuery + "%" }, sort); 
    }  

    return new CursorLoader(getActivity(), DataProvider.CONTENT_URI, grid_columns, null, null, sort); 
} 

e questo è tutto ciò che dovete fare, mi rendo conto questo è una specie di tritato ma è così perché ci sono altre cose che devono accadere, l'impostazione dell'adattatore, l'avvio del caricatore in primo luogo usando getLoaderManager().initLoader(0, null, this); e tutto il resto dei callback del caricatore che devono essere gestiti ...ma se si sta seguendo le migliori pratiche stabiliti in avanti dalla gente Android, (utilizzando LoaderManager s nei vostri ListActivity s e ListFragments s dovrebbe essere abbastanza facile per voi ...

Spero che questo aiuta non esitate a chiedere chiarimenti nei commenti se avete bisogno di -ck

+0

Grazie mille per la spiegazione dettagliata. Proverò a implementarlo nei prossimi giorni e farvi sapere se ho qualche problema. – bencallis

+0

Grazie Sono riuscito a farlo una risposta molto istruttiva, una cosa che mi stavo chiedendo.Per impostazione predefinita nell'applicazione ho 3 schede ognuna delle quali rappresenta una categoria durante la ricerca Vorrei rimuovere queste schede.Questo non è un problema, il problema che sto avendo è come faccio a sapere quando l'utente ha terminata la ricerca (tornata indietro) per aggiungere nuovamente le schede. – bencallis

+0

@bencallis ti piacerebbe più usare setOnCloseListener (listener SearchView.OnCloseListener) sul SearchView ... – ckozl