19

Come posso convertire uno ArrayAdapter<String> di dati statici in un CursorAdapter per l'utilizzo di Listener di suggerimenti in SearchView? Ho costruito il ArrayAdapter<String> da dati statici (allString)Conversione di un ArrayAdapter in CursorAdapter per l'uso in un SearchView

ArrayAdapter<String> searchAdapter = new ArrayAdapter<String>(context, R.layout.listitem, allString); 

e che uso per un MultiAutoCompleteTextView che funziona bene in dispositivi con livello di API inferiore a 11

MultiAutoCompleteTextView findTextView.setAdapter(searchAdapter); 

Tuttavia il mio obiettivo API livello è 11 e per API> 10 uso uno ActionBar all'interno del quale mi piacerebbe avere un SearchView, invece.

Ecco che cosa ho provato: Mostrano la ActionBar con la incorporato SearchView ma non dà qualche suggerimento come si farebbe nel MultiAutoCompleteTextView.

@Override 
public boolean onCreateOptionsMenu(Menu menu) {  
     MenuInflater inflater = getMenuInflater(); 

     if (android.os.Build.VERSION.SDK_INT > 10){ 
      inflater.inflate(R.menu.menu11, menu); 
      searchView = (SearchView) menu.findItem(R.id.MENU_SEARCH).getActionView(); 
      int[] to = {0}; 
      CursorAdapter cursorAdapter = new SimpleCursorAdapter(context, R.layout.listitem, null, allBusStopString, to); 
      searchView.setSuggestionsAdapter(cursorAdapter); 
      searchView.setOnSuggestionListener(new OnSuggestionListener() { 

       @Override 
       public boolean onSuggestionClick(int position) { 
        String selectedItem = (String)cursorAdapter.getItem(position); 
        Log.v("search view", selectedItem); 
        return false; 
       } 

       @Override 
       public boolean onSuggestionSelect(int position) { 
        return false; 
       } 
      }); 
     }else{ 
      inflater.inflate(R.menu.menu, menu); 
     } 

    return true; 
} 

risposta

28

Che strano SearchView.setSuggestionsAdapter accetta solo CursorAdapter.

È possibile creare MatrixCursor e riempirlo con dati dall'array di stringhe. Spero che tu abbia una piccola raccolta di dati.

Quindi passare il cursore su CursorAdapter.

String[] columnNames = {"_id","text"} 
    MatrixCursor cursor = new MatrixCursor(columnNames); 
    String[] array = getResources().getStringArray(R.array.allStrings); //if strings are in resources 
    String[] temp = new String[2]; 
    int id = 0; 
    for(String item : array){ 
     temp[0] = Integer.toString(id++); 
      temp[1] = item; 
     cursor.addRow(temp); 
    }    
    String[] from = {"text"}; 
    int[] to = {R.id.name_entry}; 
    busStopCursorAdapter = new SimpleCursorAdapter(context, R.layout.listentry, cursor, from, to); 
+0

grazie, ha funzionato. –

+1

Ho appena dovuto aggiungere _id colonna per evitare l'errore spiegato [qui] (http://stackoverflow.com/questions/3360605/column-id-does-not-exist) –

+0

Sì, infatti, ho dimenticato di '_id' – pawelzieba

11

Mi trovavo di fronte a un problema simile. È possibile utilizzare SearchView.setSuggestionsAdapter() che accetta solo CursorAdapter. D'altra parte ... qual è il punto? Se si utilizza lo standard <android.support.v7.widget.SearchView />, allora contiene SearchAutoComplete che estende AppCompatAutoCompleteTextView all'interno. Il seguente codice ha funzionato per me:

List<String> items = Lists.newArrayList(new String[] {"aaaaa", "bbbbb", "ccccc", "ddddd"}); 
SearchView searchView = (SearchView) findViewById(R.id.autocomplete_searchview); 
SearchView.SearchAutoComplete searchSrcTextView = (SearchView.SearchAutoComplete) findViewById(android.support.v7.appcompat.R.id.search_src_text); 
searchSrcTextView.setThreshold(1); 
searchSrcTextView.setAdapter(new SuggestionAdapter<String>(this, android.R.layout.simple_dropdown_item_1line, items)); 
searchSrcTextView.setOnItemClickListener(new AdapterView.OnItemClickListener() { 
    @Override 
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 
     return; 
    } 
}); 

e il seguente codice di adattatore:

public class SuggestionAdapter<T> extends ArrayAdapter<T> { 

    private List<T> items; 
    private List<T> filteredItems; 
    private ArrayFilter mFilter; 

    public SuggestionAdapter(Context context, @LayoutRes int resource, @NonNull List<T> objects) { 
     super(context, resource, Lists.<T>newArrayList()); 
     this.items = objects; 
    } 

    @Override 
    public long getItemId(int position) { 
     return position; 
    } 

    @Override 
    public T getItem(int position) { 
     return items.get(position); 
    } 

    @Override 
    public Filter getFilter() { 
     if (mFilter == null) { 
      mFilter = new ArrayFilter(); 
     } 
     return mFilter; 
    } 

    public int getCount() { 
     //todo: change to pattern-size 
     return items.size(); 
    } 

    private class ArrayFilter extends Filter { 
     @Override 
     protected FilterResults performFiltering(CharSequence prefix) { 
      FilterResults results = new FilterResults(); 

      //custom-filtering of results 
      results.values = items; 
      results.count = items.size(); 

      return results; 
     } 

     @Override 
     protected void publishResults(CharSequence constraint, FilterResults results) { 
      filteredItems = (List<T>) results.values; 
      if (results.count > 0) { 
       notifyDataSetChanged(); 
      } else { 
       notifyDataSetInvalidated(); 
      } 
     } 
    } 
} 
+0

Questo restituisce tutto, non importa ciò che si digita – Mike6679

+0

Questa è la soluzione migliore se non si dispone di un cursore reale (riempire un cursore 'manualmente' è una patch errata). Funziona per me ora, ma ho dovuto cambiare un po 'del codice di esempio: - Crea findByB per il searchAutoComplete come searchView.findViewById - Override getItems e getCounts della scheda, utilizzare filteredItems invece articoli - È ovvio che è necessario implementare la logica del filtro, come ha detto il commento '// custom-filtering of results'. Grazie mille per il codice di esempio! – AliMola

Problemi correlati