Saya telah membuat tampilan daftar di android dan saya ingin menambahkan teks edit di atas daftar dan ketika pengguna memasukkan teks daftar akan disaring sesuai dengan input pengguna
Adakah yang bisa memberi tahu saya tolong jika ada cara untuk memfilter daftar adaptor di android?
Jawaban:
Tambahkan EditText di atas tampilan daftar Anda dalam file tata letak .xml. Dan dalam aktivitas / fragmen Anda ..
lv = (ListView) findViewById(R.id.list_view); inputSearch = (EditText) findViewById(R.id.inputSearch); // Adding items to listview adapter = new ArrayAdapter<String>(this, R.layout.list_item, R.id.product_name, products); lv.setAdapter(adapter); inputSearch.addTextChangedListener(new TextWatcher() { @Override public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) { // When user changed the Text MainActivity.this.adapter.getFilter().filter(cs); } @Override public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) { } @Override public void afterTextChanged(Editable arg0) {} });
Dasarnya di sini adalah menambahkan OnTextChangeListener ke teks edit Anda dan di dalam metode callbacknya menerapkan filter ke adaptor listview Anda.
EDIT
Untuk mendapatkan filter ke BaseAdapter khusus Anda, Anda harus menerapkan antarmuka yang Dapat Difilter .
class CustomAdapter extends BaseAdapter implements Filterable { public View getView(){ ... } public Integer getCount() { ... } @Override public Filter getFilter() { Filter filter = new Filter() { @SuppressWarnings("unchecked") @Override protected void publishResults(CharSequence constraint, FilterResults results) { arrayListNames = (List<String>) results.values; notifyDataSetChanged(); } @Override protected FilterResults performFiltering(CharSequence constraint) { FilterResults results = new FilterResults(); ArrayList<String> FilteredArrayNames = new ArrayList<String>(); // perform your search here using the searchConstraint String. constraint = constraint.toString().toLowerCase(); for (int i = 0; i < mDatabaseOfNames.size(); i++) { String dataNames = mDatabaseOfNames.get(i); if (dataNames.toLowerCase().startsWith(constraint.toString())) { FilteredArrayNames.add(dataNames); } } results.count = FilteredArrayNames.size(); results.values = FilteredArrayNames; Log.e("VALUES", results.values.toString()); return results; } }; return filter; } }
Di dalam performFiltering (), Anda perlu melakukan perbandingan sebenarnya dari kueri penelusuran dengan nilai-nilai dalam database Anda. Ini akan meneruskan hasilnya ke metode publishResults () .
sumber
Terapkan adaptor Anda yang Dapat Difilter:
public class vJournalAdapter extends ArrayAdapter<JournalModel> implements Filterable{ private ArrayList<JournalModel> items; private Context mContext; ....
lalu buat kelas Filter Anda:
private class JournalFilter extends Filter{ @Override protected FilterResults performFiltering(CharSequence constraint) { FilterResults result = new FilterResults(); List<JournalModel> allJournals = getAllJournals(); if(constraint == null || constraint.length() == 0){ result.values = allJournals; result.count = allJournals.size(); }else{ ArrayList<JournalModel> filteredList = new ArrayList<JournalModel>(); for(JournalModel j: allJournals){ if(j.source.title.contains(constraint)) filteredList.add(j); } result.values = filteredList; result.count = filteredList.size(); } return result; } @SuppressWarnings("unchecked") @Override protected void publishResults(CharSequence constraint, FilterResults results) { if (results.count == 0) { notifyDataSetInvalidated(); } else { items = (ArrayList<JournalModel>) results.values; notifyDataSetChanged(); } } }
Dengan cara ini, adaptor Anda dapat difilter, Anda dapat meneruskan item filter ke filter adaptor dan melakukan pekerjaannya. Saya berharap ini akan membantu.
sumber
Jika ada yang masih tertarik dengan subjek ini, saya menemukan bahwa pendekatan terbaik untuk memfilter daftar adalah dengan membuat kelas Filter generik dan menggunakannya dengan beberapa teknik refleksi / generik dasar yang terdapat dalam paket SDK jadul Java. Inilah yang saya lakukan:
public class GenericListFilter<T> extends Filter { /** * Copycat constructor * @param list the original list to be used */ public GenericListFilter (List<T> list, String reflectMethodName, ArrayAdapter<T> adapter) { super (); mInternalList = new ArrayList<>(list); mAdapterUsed = adapter; try { ParameterizedType stringListType = (ParameterizedType) getClass().getField("mInternalList").getGenericType(); mCompairMethod = stringListType.getActualTypeArguments()[0].getClass().getMethod(reflectMethodName); } catch (Exception ex) { Log.w("GenericListFilter", ex.getMessage(), ex); try { if (mInternalList.size() > 0) { T type = mInternalList.get(0); mCompairMethod = type.getClass().getMethod(reflectMethodName); } } catch (Exception e) { Log.e("GenericListFilter", e.getMessage(), e); } } } /** * Let's filter the data with the given constraint * @param constraint * @return */ @Override protected FilterResults performFiltering(CharSequence constraint) { FilterResults results = new FilterResults(); List<T> filteredContents = new ArrayList<>(); if ( constraint.length() > 0 ) { try { for (T obj : mInternalList) { String result = (String) mCompairMethod.invoke(obj); if (result.toLowerCase().startsWith(constraint.toString().toLowerCase())) { filteredContents.add(obj); } } } catch (Exception ex) { Log.e("GenericListFilter", ex.getMessage(), ex); } } else { filteredContents.addAll(mInternalList); } results.values = filteredContents; results.count = filteredContents.size(); return results; } /** * Publish the filtering adapter list * @param constraint * @param results */ @Override protected void publishResults(CharSequence constraint, FilterResults results) { mAdapterUsed.clear(); mAdapterUsed.addAll((List<T>) results.values); if ( results.count == 0 ) { mAdapterUsed.notifyDataSetInvalidated(); } else { mAdapterUsed.notifyDataSetChanged(); } } // class properties private ArrayAdapter<T> mAdapterUsed; private List<T> mInternalList; private Method mCompairMethod; }
Dan setelah itu, satu-satunya hal yang perlu Anda lakukan adalah membuat filter sebagai kelas anggota (mungkin dalam "onCreate" Tampilan) dengan meneruskan referensi adaptor Anda, daftar Anda, dan metode yang akan dipanggil untuk pemfilteran:
this.mFilter = new GenericFilter<MyObjectBean> (list, "getName", adapter);
Satu-satunya hal yang hilang sekarang, adalah mengganti metode "getFilter" di kelas adaptor:
@Override public Filter getFilter () { return MyViewClass.this.mFilter; }
Semua selesai! Anda harus berhasil memfilter daftar Anda - Tentu saja, Anda juga harus menerapkan algoritma filter Anda dengan cara terbaik yang menggambarkan kebutuhan Anda, kode di bawah ini hanyalah sebuah contoh. . Semoga membantu, hati-hati.
sumber