2010-03-03 18 views
20

¿Cómo puedo construir una barra de búsqueda donde mientras estoy escribiendo los resultados se muestran en la ListView en el que estoy buscando?Android lista de búsqueda mientras se escribe

Por ejemplo, tengo una vista de lista con 20 cuerdas. Presiono la tecla de búsqueda y aparece la barra. Quiero cuando escribo 3 palabras o más la búsqueda comienza a ejecutarse mostrando los resultados en la vista de lista (como filtro: solo muestra las cadenas en la lista que coincide con lo que escribo)

+1

Un muy buen ejemplo es en http://www.androidpeople.com/android-listview-searchbox-sort-items – amithgc

+0

Esta solución crea una nueva matriz de datos y una nueva ListAdapter para cada personaje escrito. No puedo creer que esta sea la mejor manera de hacerlo ... –

Respuesta

13

No se puede hacer esto con la barra de búsqueda. Pero la vista de lista tiene una posibilidad de filter on key pressed, como se hace en los contactos. El usuario simplemente comienza a escribir y la lista se filtra luego. Filtrar no es realmente como buscar. Si la lista contiene la palabra foo en alguna parte y escribe oo foo será filtrada, pero si escribe fo se mantendrá incluso si el elemento de la lista es call foo foo.

Usted simplemente tiene que habilitarla:

ListView lv = getListView(); 
lv.setTextFilterEnabled(true); 

no sé cómo se hace esto, si usted no tiene un teclado de hardware. Estoy usando el droide y al comenzar a escribir, comienza la lista para filtrar y para mostrar solo los resultados coincidentes.

+0

bien, no es exactamente lo que necesito, pero es una buena solución. ¡Gracias! – xger86x

1

La mejor manera es usar la función en la barra de búsqueda o SearchManager anulando en SearchRequested en una actividad de búsqueda. Puede establecer una fuente de datos para buscar para obtener el menú desplegable automático de resultados o simplemente puede tomar la información del usuario y buscarla. Aquí está una buena visión general de SearchManager es un Además hay una demostración de trabajo en las API Demos Proyecto com.example.android.apis.app.SearchQueryResult

@Override 
public boolean onSearchRequested() { 
+2

sí ... pero no quiero obtener un menú desplegable automático. Quiero la lista donde estoy buscando actualización automática con los resultados de la búsqueda mientras estoy escribiendo, no aparece un menú desplegable. ¡Gracias! – xger86x

+0

ahh, lo siento, he entendido mal la pregunta. Sin construir tu propia vista personalizada e intentando saltar a los elementos de lista en eventos de pulsación de teclas, no sé de nada mejor. –

9

He utilizado un EditText para hacer el trabajo.

Primero crearon dos copias del vector que mantiene la lista de datos que desea buscar:

List<Map<String,String>> vehicleinfo; 
List<Map<String,String>> vehicleinfodisplay; 

Una vez que tengo los datos de la lista de alguna parte, lo copio:

for(Map<String,String>map : vehicleinfo) 
{ 
    vehicleinfodisplay.add(map); 
} 

y utilizar un SimpleAdapter para mostrar la versión de pantalla (copiado) de mis datos:

String[] from={"vehicle","dateon","dateoff","reg"}; 
int[] to={R.id.vehicle,R.id.vehicledateon,R.id.vehicledateoff,R.id.vehiclereg}; 
listadapter=new SimpleAdapter(c,vehicleinfodisplay,R.layout.vehiclelistrow,from,to); 
vehiclelist.setAdapter(listadapter); 

Luego añade un TextWatcher a la EditText que responde a un evento afterTextChanged en la limpieza de la versión de visualización de la lista y luego volviendo a añadir sólo los elementos de la otra lista que cumplen con los criterios de búsqueda (en este caso el campo "reg" contiene la cadena de búsqueda). Una vez que la lista de visualización se rellena con la lista filtrada, simplemente llamo al notifyDataSetChanged en el SimpleAdapter de la lista.

searchbox.addTextChangedListener(new TextWatcher() 
{ 
    @Override 
    public void afterTextChanged(Editable s) 
    { 
     vehicleinfodisplay.clear(); 
     String search=s.toString(); 
     for(Map<String,String>map : vehicleinfo) 
     { 
      if(map.get("reg").toLowerCase().contains(search.toLowerCase())) 
       vehicleinfodisplay.add(map); 
      listadapter.notifyDataSetChanged(); 
     } 
    }; 
    ... other overridden methods can go here ... 
}); 

Espero que esto sea útil para alguien.

+0

+1 Estaba buscando esto .... :) – BBdev

19

creo que esto es lo que busca:

http://www.java2s.com/Code/Android/2D-Graphics/ShowsalistthatcanbefilteredinplacewithaSearchViewinnoniconifiedmode.htm

Que su actividad implementar SearchView.OnQueryTextListener

y añadir los siguientes métodos:

public boolean onQueryTextChange(String newText) { 
    if (TextUtils.isEmpty(newText)) { 
     mListView.clearTextFilter(); 
    } else { 
     mListView.setFilterText(newText.toString()); 
    } 
    return true; 
} 

public boolean onQueryTextSubmit(String query) { 
    return false; 
} 
+0

¡Sí! Mucho mejor. –

+0

También debe agregar 'searchView.setOnQueryTextListener (this);' en onCreateOptionsMenu. – bvmobileapps

4

Uso siguiente código para implementar búsqueda y filtrado de lista en Android:

SearchAndFilterList.java adaptador

public class SearchAndFilterList extends Activity { 

    private ListView mSearchNFilterLv; 

    private EditText mSearchEdt; 

    private ArrayList<String> mStringList; 

    private ValueAdapter valueAdapter; 

    private TextWatcher mSearchTw; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 

     super.onCreate(savedInstanceState); 

     setContentView(R.layout.activity_search_and_filter_list); 

     initUI(); 

     initData(); 

     valueAdapter=new ValueAdapter(mStringList,this); 

     mSearchNFilterLv.setAdapter(valueAdapter); 

     mSearchEdt.addTextChangedListener(mSearchTw); 


    } 
    private void initData() { 

     mStringList=new ArrayList<String>(); 

     mStringList.add("one"); 

     mStringList.add("two"); 

     mStringList.add("three"); 

     mStringList.add("four"); 

     mStringList.add("five"); 

     mStringList.add("six"); 

     mStringList.add("seven"); 

     mStringList.add("eight"); 

     mStringList.add("nine"); 

     mStringList.add("ten"); 

     mStringList.add("eleven"); 

     mStringList.add("twelve"); 

     mStringList.add("thirteen"); 

     mStringList.add("fourteen"); 

     mSearchTw=new TextWatcher() { 

      @Override 
      public void onTextChanged(CharSequence s, int start, int before, int count) { 

       valueAdapter.getFilter().filter(s); 
      } 

      @Override 
      public void beforeTextChanged(CharSequence s, int start, int count, 
        int after) { 

      } 

      @Override 
      public void afterTextChanged(Editable s) { 

      } 
     }; 

    } 

    private void initUI() { 

     mSearchNFilterLv=(ListView) findViewById(R.id.list_view); 

     mSearchEdt=(EditText) findViewById(R.id.txt_search); 
    } 

} 

Valor: ValueAdapter.java

public class ValueAdapter extends BaseAdapter implements Filterable{ 

    private ArrayList<String> mStringList; 

    private ArrayList<String> mStringFilterList; 

    private LayoutInflater mInflater; 

    private ValueFilter valueFilter; 

    public ValueAdapter(ArrayList<String> mStringList,Context context) { 

     this.mStringList=mStringList; 

     this.mStringFilterList=mStringList; 

     mInflater=LayoutInflater.from(context); 

     getFilter(); 
    } 

    //How many items are in the data set represented by this Adapter. 
    @Override 
    public int getCount() { 

     return mStringList.size(); 
    } 

    //Get the data item associated with the specified position in the data set. 
    @Override 
    public Object getItem(int position) { 

     return mStringList.get(position); 
    } 

    //Get the row id associated with the specified position in the list. 
    @Override 
    public long getItemId(int position) { 

     return position; 
    } 

    //Get a View that displays the data at the specified position in the data set. 
    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 

     Holder viewHolder; 

     if(convertView==null) { 

      viewHolder=new Holder(); 

      convertView=mInflater.inflate(R.layout.list_item,null); 

      viewHolder.nameTv=(TextView)convertView.findViewById(R.id.txt_listitem); 

      convertView.setTag(viewHolder); 

     }else{ 

      viewHolder=(Holder)convertView.getTag(); 
     } 

      viewHolder.nameTv.setText(mStringList.get(position).toString()); 

      return convertView; 
    } 

    private class Holder{ 

     TextView nameTv; 
    } 

    //Returns a filter that can be used to constrain data with a filtering pattern. 
    @Override 
    public Filter getFilter() { 

     if(valueFilter==null) { 

      valueFilter=new ValueFilter(); 
     } 

     return valueFilter; 
    } 


    private class ValueFilter extends Filter { 


     //Invoked in a worker thread to filter the data according to the constraint. 
     @Override 
     protected FilterResults performFiltering(CharSequence constraint) { 

      FilterResults results=new FilterResults(); 

      if(constraint!=null && constraint.length()>0){ 

       ArrayList<String> filterList=new ArrayList<String>(); 

       for(int i=0;i<mStringFilterList.size();i++){ 

        if(mStringFilterList.get(i).contains(constraint)) { 

         filterList.add(mStringFilterList.get(i)); 

        } 
       } 


       results.count=filterList.size(); 

       results.values=filterList; 

      }else{ 

       results.count=mStringFilterList.size(); 

       results.values=mStringFilterList; 

      } 

      return results; 
     } 


     //Invoked in the UI thread to publish the filtering results in the user interface. 
     @SuppressWarnings("unchecked") 
     @Override 
     protected void publishResults(CharSequence constraint, 
       FilterResults results) { 

      mStringList=(ArrayList<String>) results.values; 

      notifyDataSetChanged(); 


     } 

    } 

} 

activity_search_and_filter_list.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" > 

    <EditText 
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content" 
     android:id="@+id/txt_search" 
     tools:context=".SearchAndFilterList" 
     android:hint="Enter text to search" /> 
    <ListView 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:id="@+id/list_view" 
     android:layout_below="@+id/txt_search"></ListView> 

</RelativeLayout> 

list_item.xml

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" > 
    <TextView 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:id="@+id/txt_listitem"/> 

</RelativeLayout> 

AndroidManifext.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="com.example.searchandfilterlistview" 
    android:versionCode="1" 
    android:versionName="1.0" > 

    <uses-sdk 
     android:minSdkVersion="8" 
     android:targetSdkVersion="15" /> 

    <application 
     android:icon="@drawable/ic_launcher" 
     android:label="@string/app_name" 
     android:theme="@style/AppTheme" > 
     <activity 
      android:name=".SearchAndFilterList" 
      android:label="@string/title_activity_search_and_filter_list" > 
      <intent-filter> 
       <action android:name="android.intent.action.MAIN" /> 

       <category android:name="android.intent.category.LAUNCHER" /> 
      </intent-filter> 
     </activity> 
    </application> 

</manifest> 

espero que este código se hará útil para poner en práctica la costumbre de búsqueda y filtro de vista de lista

Cuestiones relacionadas