2010-03-03 19 views
20

Jak mogę zbudować pasek wyszukiwania, gdzie podczas pisania wyników są wyświetlane w ListView, w których szukam?Lista wyszukiwania Androida podczas pisania

Na przykład mam widok listy z 20 ciągami. Naciskam klawisz wyszukiwania i pojawia się pasek. Chcę, gdy wpiszę 3 słowa lub więcej, rozpocznie się wyszukiwanie, pokazując wyniki w widoku listy (jako filtr: pokazuje tylko ciągi z listy, które pasują do tego, co wpisuję)

+1

Bardzo dobrym przykładem jest http://www.androidpeople.com/android-listview-searchbox-sort-items – amithgc

+0

To rozwiązanie tworzy nową tablicę danych i nowy ListAdapter dla każdego wpisanego znaku. Nie mogę uwierzyć, że to jest najlepszy sposób, aby to zrobić .. –

Odpowiedz

13

Nie można tego zrobić z paska wyszukiwania. Ale listview ma możliwość filter on key pressed, tak jak to się dzieje w kontaktach. Użytkownik po prostu zaczyna pisać, a następnie lista zostaje przefiltrowana. Filtrowanie nie przypomina wyszukiwania. Jeśli lista zawiera gdzieś słowo foo i wpisujesz oo oo foo zostanie odfiltrowane, ale jeśli wpiszesz fo, pozostanie ono nawet wtedy, gdy pozycja listu to bar foo.

Po prostu musisz ją włączyć:

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

nie wiem jak to zrobić, jeśli nie masz klawiatury sprzętowej. Używam droida i zaczynam pisać, aby rozpocząć filtrowanie i pokazywanie tylko pasujących wyników.

+0

OK, nie jest to dokładnie to, czego potrzebuję, ale jest to dobre rozwiązanie. dzięki! – xger86x

1

Najlepszym sposobem jest użycie zbudowanego w pasku wyszukiwania lub menedżerze wyszukiwania SearchManager przez przesłonięcie obiektu OnSearchRequest w akcie przeszukiwalnym. Możesz ustawić źródło danych do wyszukiwania, aby uzyskać automatyczne upuszczanie wyników lub możesz po prostu wziąć dane wejściowe od użytkownika i wyszukać. Tu jest dobry przegląd SearchManager jest Plus nie jest demo działa w API Demos projekt com.example.android.apis.app.SearchQueryResult

@Override 
public boolean onSearchRequested() { 
+2

tak .. ale nie chcę uzyskać automatycznego rozwijania wyników. Chcę, aby lista, na której szukam automatycznego odświeżania z wynikami wyszukiwania podczas pisania, nie pojawia się menu rozwijane. Dzięki! – xger86x

+0

ahh, przepraszam, źle zrozumiałem pytanie. Nie budując własnego, niestandardowego widoku i próbując skakać na listę zdarzeń kluczowych, nie znam nic lepszego. –

9

Do wykonania pracy użyłem EditText.

Najpierw stworzył dwie kopie tablicy do przechowywania listy danych do wyszukiwania:

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

Raz mam moja lista danych skądś skopiować go:

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

i użyć SimpleAdapter aby wyświetlić menu (skopiowany) wersję moich danych:

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

Potem dodał TextWatcher do EditText, który odpowiada na zdarzenie afterTextChanged przez wyczyszczenie wyświetlanej wersji listy, a następnie dodanie z powrotem tylko elementów z innej listy, które spełniają kryteria wyszukiwania (w tym przypadku pole "reg" zawiera ciąg wyszukiwania). Po zapełnieniu listy wyświetlania przefiltrowaną listą, po prostu zadzwonię pod numer notifyDataSetChanged na listę SimpleAdapter z listy.

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

Mam nadzieję, że jest to pomocne dla kogoś.

+0

+1 szukałem tego .... :) – BBdev

19

Wierzę, że to jest to, czego szukasz:

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

Wyraź swoją aktywność realizować SearchView.OnQueryTextListener

i dodaj następujące metody:

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

Tak! Dużo lepiej. –

+0

Należy również dodać 'searchView.setOnQueryTextListener (this);' in onCreateOptionsMenu. – bvmobileapps

4

użyć poniższy kod do wdrożenia wyszukiwania i filtrowania listy w Androidzie:

SearchAndFilterList.java

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

} 

Niestandardowe Wartość adapter: 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> 

Mam nadzieję, że ten kod będzie przydatne do zaimplementowania wyszukiwania niestandardowego i filtra listview

Powiązane problemy