2013-02-23 4 views
3

В этом Stackoverflow answer, указывается, что фильтрация может быть выполнена в ListView без перекрывая getFilter метод ArrayAdapter и вместо реализации toString в POJO классе.Фильтрация ListView с использованием ArrayAdapter без переопределения метода getFilter

Я попытался реализовать его, но фильтрация работает некорректно. Хотя фильтр ListView фильтрует, он не отображает правильные элементы в массиве. Так, например, если фильтр соответствует одной строке в array, тогда один элемент отображается в ListView, но это неправильный элемент, который показан. В этом случае всегда отображается первый элемент массива, а не элемент, который фактически соответствует введенному поисковому тексту.

Вот код для моего ArrayAdapter:

public class TitleListingArrayAdapter extends ArrayAdapter<Title> { 

    private List<Title> items; 
    private Context context; 

    public TitleListingArrayAdapter(Context context, int textViewResourceId, List<Title> items) { 
     super(context, textViewResourceId, items); 
     this.items = items; 
     this.context = context; 
    } 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) 
    { 
     View view = convertView; 
     if (view == null) { 
      LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
      view = inflater.inflate(R.layout.titlelisting_single_row, null); 
     } 
     Title item = items.get(position); 
     if (item!= null) { 
      TextView titleView = (TextView) view.findViewById(R.id.title);    
      if (titleView != null) { 
       titleView.setText(item.getName()); 
      } 
      TextView yearView = (TextView) view.findViewById(R.id.year); 
      if (yearView != null) { 
       yearView.setText(String.valueOf(item.getYear())+", "); 
      } 
      TextView genreView = (TextView) view.findViewById(R.id.genre); 
      if (genreView != null) { 
       genreView.setText(item.getGenre()); 
      } 
      TextView authorView = (TextView) view.findViewById(R.id.author); 
      if (authorView != null) { 
       authorView.setText(item.getAuthor()); 
      } 
      RatingBar ratingView = (RatingBar) view.findViewById(R.id.rating); 
      if (ratingView != null) { 
       ratingView.setRating(item.getRating()); 
      } 
      ImageView iconView = (ImageView) view.findViewById(R.id.list_image); 
      iconView.setImageResource(lookupResourceId(context, item.getID()));    
     } 
     return view; 
    } 

    private int lookupResourceId(Context context, String id) { 
     String resourceName = "thumb_"+id; 
     return context.getResources().getIdentifier(resourceName, "drawable", context.getPackageName()); 
    } 
} 

Вот соответствующий раздел моего Activity кода:

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.listing); 
    databaseHandler = new DatabaseHandler(this); 
    listView = (ListView) findViewById(R.id.list); 
    List<Title> titles = databaseHandler.getAllTitles(); 
    adapter = new TitleListingArrayAdapter(this, R.id.list, titles); 
    listView.setAdapter(adapter); 
    filterText = (EditText) findViewById(R.id.filter); 
    filterText.addTextChangedListener(filterTextWatcher); 
} 

private TextWatcher filterTextWatcher = new TextWatcher() { 
    public void afterTextChanged(Editable s) {} 
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {} 
    public void onTextChanged(CharSequence s, int start, int before, int count) { 
     adapter.getFilter().filter(s.toString().toLowerCase()); 
    } 
}; 

Название POJO класс реализует ToString следующим образом:

@Override 
public String toString() { 
    String name = this.getName() == null ? "" : this.getName().toLowerCase(); 
    String year = this.getYear() == null ? "" : this.getYear().toString(); 
    String genre = this.getGenre() == null ? "" : this.getGenre().toLowerCase(); 
    return name + " " +year+ " "+ genre; 
} 

Кто-нибудь знает, почему фильтрация не является правильно орки и как я могу это исправить?

+0

Не могли бы вы привести несколько примеров того, что вы ожидаете и чего вы на самом деле получаете? – Sam

+0

Осмотрите свой код: вы должны реализовать ViewHolders (см. [Турбо-зарядка вашего пользовательского интерфейса Google] (http://www.google.com/events/io/2009/sessions/TurboChargeUiAndroidFast.html)), 'toLowerCase()' [избыточно] (http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.1.2_r1/android/widget/ArrayAdapter.java#ArrayAdapter.ArrayFilter.performFiltering % 28java.lang.CharSequence% 29), поэтому вы можете удалить это, и я рекомендую придерживаться Cursors, CursorAdapters и FilterQueryProviders при работе с базами данных. Они намного быстрее, чем преобразование всего в списки. – Sam

+0

Спасибо, Сэм, за информацию. Я теперь реализовал 'ViewHolders' в моем« ArrayAdapter »и смотрю на замену« ArrayAdapter »на« CursorAdapter ». Я использовал «ArrayAdapter», потому что я новичок в разработке «Android» и примере «ListView», который нашел и основал мой код, используя «ArrayAdapter». Я буду исследовать 'Cursors' и' CursorAdapters'. Благодарю. – BruceHill

ответ

5

question касается именно той же проблемы, с которой я столкнулся. Этот вопрос также дает пример того, что делает фильтрация, показывая правильный номер элементов, не отображая правильные элементы в списке.

Похоже, что этот answer ошибочен, несмотря на то, что он был увеличен шесть раз. Я решил это, не используя метод getFilter для ArrayAdapter. Скорее всего, я создаю в моем TextWatcher например новый ArrayAdapter следующим образом:

private TextWatcher filterTextWatcher = new TextWatcher() { 
    public void afterTextChanged(Editable s) {} 
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {} 
    public void onTextChanged(CharSequence s, int start, int before, int count) { 
     if (!s.toString().equals("")) { 
       List<Title> filteredTitles = new ArrayList<Title>(); 
       for (int i=0; i<titles.size(); i++) { 
        if (titles.get(i).toString().contains(s)) { 
         filteredTitles.add(titles.get(i));     
        }    
       } 
       adapter = new TitleListingArrayAdapter(TitleListingActivity.this, R.id.list, filteredTitles); 
       listView.setAdapter(adapter); 
     } 
     else { 
       adapter = new TitleListingArrayAdapter(TitleListingActivity.this, R.id.list, titles); 
       listView.setAdapter(adapter);    
     } 
    } 
}; 

Обратите внимание, что я переехал заявление List<Title> titles из onCreate и сделал это переменная член моего Activity класса, так что он доступен внутри onTextChanged способ filterTextWatcher.

+0

«R.id.list» происходит от того, где? У меня проблема с моим адаптером: http://stackoverflow.com/questions/20524417/listview-is-blank-while-using-getfilter-function – Si8

+0

Это он помощник! Это оно!Это то, что я искал, и теперь я, надеюсь, завершу свое техническое задание на собеседование. Большое спасибо! –

Смежные вопросы