2009-10-29 11 views
31

Mam ListView i EditText. Jak mogę filtrować dane ListView podczas pisania na EditText?Jak mogę filtrować dane ListView podczas pisania w EditText w Androidzie

+1

Johe, Zajrzyj tutaj, wyjaśnienie jest BARDZO jasne. http://stackoverflow.com/questions/1901020/android-xml-list-view-with-filter/2282012#2282012 – Sephy

+1

Pomyśl, czy moje rozwiązanie może być właśnie tym, czego szukasz! Hamy

+0

[Przeczytaj to] (http://stackoverflow.com/a/1737042/523325) za dobre rozwiązanie. –

Odpowiedz

27
  1. Dodaj TextWatcher do EditText#addTextChangedListener
  2. W onTextChanged dodaj lub usuń elementy z adaptera ListView. Jeśli są instacji ArrayAdapter musiałby add i remove metod
+0

To działa! Dzięki! – Dennie

-1

1) utworzyć kartę niestandardową do widoku listy i utworzyć removeIfMatch() metoda łańcucha S:

public void removeIfMatch(String s) { 
    for item in adapter: 
    if item.matches(s) { 
     data.removeItem(item); 
     notifyDataSetChanged(); 
     break 
    } 
} 

2) Utwórz wywołania zwrotnego dla kiedy zawartość EditText zmienić

3) powołać adaptera .removeIfMatch (editText.getText())

+2

Co się stanie, jeśli ktoś nad typem uderzy w klawisz Backspace? –

+2

Dostępne są już filtry filtrów. Twoje rozwiązanie zmienia dane na twojej liście. Podobnie jak fiXedd zwrócił uwagę, czy naciśnięty przycisk Backspace zostanie usunięty. Nie powinieneś odkrywać koła na nowo. –

8

Można użyć:

http://developer.android.com/reference/android/widget/TextView.html

addTextChangedListener(TextWatcher watcher)

aby dowiedzieć się, kiedy TextView został zmieniony. Uważam, że powinno to być wywoływane za każdym razem, gdy zostanie dodana lub usunięta litera.

Następnie zaktualizować listę adapter do dislplay nowe przedmioty przez:

  1. tworzenia nowej listy zasilacz i wypełniania go z rzeczami, które spełniają filtr lub
  2. mającą podklasę BaseAdapter przyjąć Twój filtr i nazywają notifyDataSetChanged() po jej zakończeniu usuwania przedmiotów nie chcesz już

http://developer.android.com/reference/android/widget/BaseAdapter.html

+0

Więc masz na myśli dla TextView? Używam EditText. W każdym razie myślę, że jest to również przydatne dla mnie! dzięki! – Dennie

+0

Przepraszamy. Na szczęście EditText jest podklasą TextView i nadal jest trafny. Cieszę się, że pomogło. – user175750

3

Szukaj listview oparte na wejściu w EditText

 public class MainActivity extends Activity { 
private ListView lv,lv2; 
private EditText et; 
String listview_array[]={"01634 ABOHAR","080 Bangalore","011 Delhi","Dell Inspiron", "HTC One X", "HTC Wildfire S", "HTC Sense", "1234", "iPhone 4S", "Samsung Galaxy Note 800", "Samsung Galaxy S3", "MacBook Air", "Mac Mini", "MacBook Pro"}; 
private ArrayList<String> array_sort = new ArrayList<String>(); 
int textlength = 0; 

public void onCreate(Bundle savedInstanceState) 

{ 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
    lv = (ListView) findViewById(R.id.ListView01); 
    lv2 = (ListView) findViewById(R.id.ListView02); 
    et = (EditText) findViewById(R.id.EditText01); 
    lv.setAdapter(new ArrayAdapter<String>(this, 
    android.R.layout.simple_list_item_1, listview_array)); 
    int x= lv.getHeaderViewsCount(); 
    System.out.println("x========"+x); 
    lv.setAdapter(new ArrayAdapter<String> 
    (MainActivity.this, 
    android.R.layout.simple_list_item_1, listview_array)); 

    et.addTextChangedListener(new TextWatcher() 
    { 
     public void afterTextChanged(Editable s) 
     { 
      // Abstract Method of TextWatcher Interface. 

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

      // Abstract Method of TextWatcher Interface. 

     } 
     public void onTextChanged(CharSequence s, 
     int start, int before, int count) 
     { 
      textlength = et.getText().length(); 
      array_sort.clear(); 
      for (int i = 0; i < listview_array.length; i++) 
      { 
       if (textlength <= listview_array[i].length()) 
       { 

        String s2= et.getText().toString(); 
        if(listview_array[i].toString().contains(et.getText().toString())) 
        { 
         array_sort.add(listview_array[i]); 
        } 


       } 
      } 

      lv.setAdapter(new ArrayAdapter<String> 
      (MainActivity.this, 
      android.R.layout.simple_list_item_1, array_sort)); 
     } 
    }); 

} 
} 

Dla wyszukiwania w niestandardowych pogrupowanych na podstawie pozycji klasowej patrz odnośnik implement search on a custom listview. Zmodyfikuj go zgodnie ze swoimi potrzebami.

+0

Mine był niestandardowym listView nawet po tym, kod w onTextChanged() działał dobrze. –

24

Tak, możesz zaimplementować ten kod. Należy użyć następującego kodu do realizacji przeszukiwania 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); 
    } 

} 

adapter klienta Wartość: 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 woli pomocne do realizacji niestandardowych wyszukiwania i filtrowania listview.

+1

Wywołanie metody adaptor.getFilter(). Filtr (y) w afterTextChanged() –

Powiązane problemy