2015-01-14 2 views
0

Ничего не происходит, даже я вводил точное «ключевое» имя в EditText, тогда как оно должно показывать только эту запись в списке.Фильтр поиска не работает

Фильтрация не работает, это как моя JSON выглядит следующим образом:

{ 
    "data": [ 
    { 
     "id": "1", 
     "name": "Era Locksmith", 
     "key": "EraLoc2015" 
    }, 
    { 
     "id": "2", 
     "name": "Mac Garage Door", 
     "key": "MacGdr2015" 
    } 
    ] 
} 

Я простирающийся ArrayAdapter < ....> и реализации Фильтруемые

CompanyListAdapter.java:

public class CompanyListAdapter extends ArrayAdapter<Company> implements Filterable { 

    private Context context; 
    ArrayList<Company> products; 
    SharedPreference sharedPreference; 

    private ArrayList<Company> filteredCompanies; 
    private CompanyFilter mFilter = new CompanyFilter(); 

    public CompanyListAdapter(Context context, ArrayList<Company> products) { 
     super(context, R.layout.company_list_item, products); 
     this.context = context; 
     this.products = products; 
     sharedPreference = new SharedPreference(); 
    } 

    @Override 
    public Filter getFilter() { 
     return mFilter; 
    } 

    private class ViewHolder { 
     TextView productNameTxt; 
     TextView productKeyTxt; 
     ImageView favoriteImg; 
    } 

    @Override 
    public int getCount() { 
     return products.size(); 
    } 

    @Override 
    public Company getItem(int position) { 
     return products.get(position); 
    } 

    @Override 
    public long getItemId(int position) { 
     return 0; 
    } 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 
     ViewHolder holder = null; 
     if (convertView == null) { 
      LayoutInflater inflater = (LayoutInflater) context 
        .getSystemService(Activity.LAYOUT_INFLATER_SERVICE); 
      convertView = inflater.inflate(R.layout.company_list_item, null); 
      holder = new ViewHolder(); 
      holder.productNameTxt = (TextView) convertView 
        .findViewById(R.id.txt_pdt_name); 
      holder.productKeyTxt = (TextView) convertView 
        .findViewById(R.id.txt_pdt_price); 
      holder.favoriteImg = (ImageView) convertView 
        .findViewById(R.id.imgbtn_favorite); 

      convertView.setTag(holder); 
     } else { 
      holder = (ViewHolder) convertView.getTag(); 
     } 
     Company product = (Company) getItem(position); 
     holder.productNameTxt.setText(product.getName()); 
     holder.productKeyTxt.setText(product.getPrice() + ""); 

     /*If a product exists in shared preferences then set heart_red drawable 
     * and set a tag*/ 
     if (checkFavoriteItem(product)) { 
      holder.favoriteImg.setImageResource(R.drawable.heart_red); 
      holder.favoriteImg.setTag("red"); 
     } else { 
      holder.favoriteImg.setImageResource(R.drawable.heart_grey); 
      holder.favoriteImg.setTag("grey"); 
     } 

     return convertView; 
    } 

    /*Checks whether a particular product exists in SharedPreferences*/ 
    public boolean checkFavoriteItem(Company checkProduct) { 
     boolean check = false; 
     List<Company> favorites = sharedPreference.getFavorites(context); 
     if (favorites != null) { 
      for (Company product : favorites) { 
       if (product.equals(checkProduct)) { 
        check = true; 
        break; 
       } 
      } 
     } 
     return check; 
    } 

    @Override 
    public void add(Company product) { 
     super.add(product); 
     products.add(product); 
     notifyDataSetChanged(); 
    } 

    @Override 
    public void remove(Company product) { 
     super.remove(product); 
     products.remove(product); 
     notifyDataSetChanged(); 
    } 

    private class CompanyFilter extends Filter { 
     @Override 
     protected FilterResults performFiltering(CharSequence constraint) { 

      String filterString = constraint.toString().toLowerCase(); 
      FilterResults results = new FilterResults(); 

      final List<Company> list = products; 

      int count = list.size(); 
      final ArrayList<Company> nlist = new ArrayList<Company>(count); 

      Company filterableCompany; 

      for (int i = 0; i < count; i++) { 
       filterableCompany = list.get(i); 
       if (filterableCompany.getKey().toLowerCase().contains(filterString)) { 
        nlist.add(filterableCompany); 
       } 
      } 

      results.values = nlist; 
      results.count = nlist.size(); 

      return results; 
     } 

     @SuppressWarnings("unchecked") 
     @Override 
     protected void publishResults(CharSequence constraint, FilterResults results) { 
      filteredCompanies = (ArrayList<Company>) results.values; 
      notifyDataSetChanged(); 
     } 
    } 

} 

Использование EditText для принятия "ключ"

CompanyListActivity.java:

EditText filterList = (EditText) view.findViewById(R.id.editKey); 
     filterList.addTextChangedListener(new TextWatcher() { 

      @Override 
      public void onTextChanged(CharSequence s, int start, int before, int count) { 
       // TODO Auto-generated method stub 
       productListAdapter.getFilter().filter(s.toString()); 
      } 

      @Override 
      public void beforeTextChanged(CharSequence s, int start, int count, 
        int after) { 
       // TODO Auto-generated method stub 

      } 

      @Override 
      public void afterTextChanged(Editable s) { 
       // TODO Auto-generated method stub 

      } 
     }); 

Я использую код, предоставленный @Leigh

+0

возможно дубликат [Просмотреть список фильтров Android ] (http://stackoverflow.com/questions/14663725/list-view-filter-android) – 2Dee

ответ

1

Почему бы не использовать implement Filterable? Попробуйте что-то вроде этого:

сделать адаптер класса выглядеть следующим образом:

public class CompanyListAdapter extends ArrayAdapter<Company> implements Filterable { 

    private List<Company> companies; 
    private List<Company> filteredCompanies; 
    private CompanyFilter mFilter = new CompanyFilter(); 

    private Context context; 
    SharedPreference sharedPreference; 

    public CompanyListAdapter(Context context, ArrayList<Company> products) { 
     super(context, R.layout.company_list_item, products); 
     this.context = context; 
     this.products = products; 
     this.filteredCompanies = products; 
     sharedPreference = new SharedPreference(); 
    } 

    @Override 
    public int getCount() { 
     return filteredCompanies == null 0 : filteredCompanies.size(); 
    } 

    @Override 
    public Company getItem(int position) { 
     return filteredCompanies.get(position); 
    } 

    @Override 
     public Filter getFilter() { 
     return mFilter; 
    } 
} 

Следующая идти вперед и создать CompanyFilter:

private class CompanyFilter extends Filter { 
    @Override 
    protected FilterResults performFiltering(CharSequence constraint) { 

     String filterString = constraint.toString().toLowerCase(); 
     FilterResults results = new FilterResults(); 

     final List<Company> list = companies; 

     int count = list.size(); 
     final ArrayList<Company> nlist = new ArrayList<Company>(count); 

     Company filterableCompany; 

     for (int i = 0; i < count; i++) { 
      filterableCompany = list.get(i); 
      if (filterableCompany.getName().toLowerCase().contains(filterString)) { 
       nlist.add(filterableCompany); 
      } 
     } 

     results.values = nlist; 
     results.count = nlist.size(); 

     return results; 
    } 

    @SuppressWarnings("unchecked") 
    @Override 
    protected void publishResults(CharSequence constraint, FilterResults results) { 
     filteredCompanies = (ArrayList<Company>) results.values; 
     notifyDataSetChanged(); 
    } 
} 

Таким образом, вы получите, чтобы применить фильтр к любому количество полей. Примечание. Я использую getName() класса компании, чтобы применить фильтр в моем примере.

EDIT: использовать это в качестве Activity/Fragment для поиска вы можете добавить к вашему TextWatcherEditText и примените фильтр onTextChanged. Что-то вроде этого:

txtSearch.addTextChangedListener(new TextWatcher() { 

    @Override 
    public void onTextChanged(CharSequence s, int start, int before, int count) { 
     adapter.getFilter().filter(s.toString()); 
    } 
}); 
+0

отличный код, но немного путайте, как этот код подключен к моему EditText? – Sun

+0

@Sun см. Мое редактирование, которое дает вам пример того, как вы могли использовать фильтр против вашего адаптера. – Leigh

+0

, пожалуйста, проверьте мой обновленный код, следуя за вами – Sun

0

вам нужно сделать адаптер реализовать Filterable так:

class CustomAdapter extends BaseAdapter implements Filterable { 
    @Override 
     public Filter getFilter() { ...} 

попытка взглянуть на этот ответ:
List View Filter Android