19

¿Cómo puedo convertir un ArrayAdapter<String> de datos estáticos en un CursorAdapter para usar el Listener de sugerencia en SearchView? he construido el ArrayAdapter<String> a partir de datos estáticos (allString)Conversión de un ArrayAdapter a CursorAdapter para su uso en un SearchView

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

y lo uso para un MultiAutoCompleteTextView que funciona muy bien en los dispositivos con un nivel de API de menos de 11

MultiAutoCompleteTextView findTextView.setAdapter(searchAdapter); 

Sin embargo, mi API objetivo nivel es 11 y para API> 10 utilizo un ActionBar dentro del cual me gustaría tener un SearchView en su lugar.

Esto es lo que he intentado: Muestra el ActionBar con el SearchView incrustado pero no da ninguna sugerencia como lo haría en el 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; 
} 

Respuesta

28

eso es extraño SearchView.setSuggestionsAdapter sólo acepta CursorAdapter.

Puede crear MatrixCursor y completarlo con datos de String array. Espero que tengas una pequeña recopilación de datos.

Luego, pase el cursor a 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

gracias, funcionó. –

+1

Solo tuve que agregar la columna _id para evitar el error explicado [aquí] (http://stackoverflow.com/questions/3360605/column-id-does-not-exist) –

+0

Sí, de hecho, me olvidé de '_id' – pawelzieba

11

Me enfrentaba un problema similar. Puede usar SearchView.setSuggestionsAdapter() que solo acepta CursorAdapter. Por otro lado ... ¿cuál es el punto? Si usa el estándar <android.support.v7.widget.SearchView />, entonces contiene SearchAutoComplete que extiende AppCompatAutoCompleteTextView dentro. El siguiente código que funcionó para mí:

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; 
    } 
}); 

y el siguiente código de adaptador:

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

Esto devuelve todo sin importar lo que escriba – Mike6679

+0

Esta es la mejor solución si no tiene un cursor real (llenar un cursor 'manualmente' es un parche incorrecto). Ahora me funciona, pero necesitaba cambiar parte del código de ejemplo: - Haga findViewById para la búsqueda Autocompletar como searchView.findViewById - Reemplazar getItems y getCounts del adaptador, usar filteredItems en su lugar artículos - Es obvio que debe implementar su lógica de filtro, como dice el comentario '// filtrado personalizado de resultados'. ¡Muchas gracias por el código de ejemplo! – AliMola

Cuestiones relacionadas