2015-11-16 3 views
1

В простом приложении для Android, которое использовало ArrayList и ArrayAdapter для заполнения AutoCompleteTextView, теперь я заменил ArrayAdapter на пользовательский адаптер. Причина в том, что мне нужно удалить пробелы и некоторые другие символы из введенного текста, прежде чем искать список (т. Е. Ввод «OM» должен быть нормализован в «OM», а затем должны отображаться предложения, начинающиеся с «OM».Custom ArrayAdapter getFilter() не называется

я попытался сделать это в следующем совершить на GitHub:. https://github.com/Natureshadow/MirWTFApp/commit/260a4deaee449cb63d3af3c446c94466b90f736c

обычай адаптер имеет метод getFilter, который должен возвращать пользовательский фильтр делает нормализацию, но getFilter() никогда не вызывается

что может Я могу выяснить, почему это не вызвано, и как я могу заставить приложение использовать настраиваемый фильтр?

У StackOverflow есть некоторые вопросы, которые описывают подобную проблему, но все эти вопросы включают в себя изменение обработки данных ArrayList в пользовательском адаптере, чего я не делал.

+0

Укажите код плз. –

+0

как сделать вашу жизнь более трудной и реализовать материал 'Filter' вообще? откуда берутся данные для вашего автозаполнения? какова ваша модель данных? – pskink

+0

@tinysunlight wellm есть ссылка на GitHub ... –

ответ

1

Решения заканчивало тем обычай ArrayAdapter подкласса, который присоединяет фильтр перед ArrayFilter даже не видит.

Изменение основного приложения минимально, ему просто нужно создать экземпляр недавно окрещенного WtfArrayAdapter и передать его конструктору дополнительный аргумент: ссылка на объект, содержащий метод нормализации (в текущем дизайне äpp, это MainActivity класса, будущий рефакторинг будет лучше):

-  ArrayAdapter acronymKeys = new ArrayAdapter(this, 
-   android.R.layout.simple_list_item_1, sorted); 
+  ArrayAdapter acronymKeys = new WtfArrayAdapter(this, 
+   android.R.layout.simple_list_item_1, sorted, this); 

обычай WtfArrayAdapter должен иметь возможность вызывать методы из ArrayFilter (который ArrayAdapter «s внутреннего частный класса), поэтому она должна принадлежать package android.widget;.Я избавлю вас full imports, comments, etc. и воспроизводить важные детали ниже:

public class WtfArrayAdapter<T> extends ArrayAdapter<T> { 

новых членов: - объект Предфильтровая метод нормализации в - наш внутренний частный класс объект - внутренний частный класс родителя 'объект (ArrayAdapter.mFilter является private, к сожалению)

private MainActivity sParent; 
    private WtfArrayFilter sFilter; 
    private Filter pFilter; 

выдвинутом конструктор (нам необходимо реализовать только один, мы на самом деле вызов): - вызов унаследованного Конструктор - хранить вдали mFilter значение родительского - экземпляр нашей собственной WtfArrayFilter - хранить вдали объект Предфильтровая метод нормализации, поскольку WtfArrayFilter потребуется позже

public WtfArrayAdapter(Context context, @LayoutRes int resource, 
     @NonNull T[] objects, MainActivity parent) { 
     super(context, resource, 0, Arrays.asList(objects)); 
     sParent = parent; 
     sFilter = new WtfArrayFilter(); 
     pFilter = super.getFilter(); 
    } 

Override ArrayAdapter «s getFilter() метод всегда возвращает наши новый WtfArrayFilter:

public Filter getFilter() { 
     return sFilter; 
    } 

Реализация WtfArrayFilter как Filter подкласса просто например ArrayFilter, и пересылка всех буровых (т. без изменений) вызывают к унаследованным ArrayFilter:

private class WtfArrayFilter extends Filter { 
     protected void publishResults(CharSequence constraint, 
      FilterResults results) { 
      pFilter.publishResults(constraint, results); 
     } 

Нам нужно изменить только один метод, чтобы сделать нашу собственную фильтрацию перед вызовом унаследованного ArrayFilter «s метода фильтрации:

 protected FilterResults performFiltering(CharSequence prefix) { 
      return pFilter.performFiltering(prefix == null ? null : 
       sParent.normaliseAcronym(prefix.toString())); 
     } 
    } 
} 

Улучшения приветствуются, я все еще новичок Java ™.

0
ArrayList<YourModel> listFromActivity= null; 
    ArrayList<YourModel> mainList; 

    public MyConstructor(Context context, ArrayList<YourModel> listFromActivity) { 
     this.context = context; 
     this.listFromActivity= listFromActivity; 
     mainList= new ArrayList<>(); 
     mainList.addAll(listFromActivity); 

    }  

public void filter(String charText) { 
      charText = charText.toLowerCase(Locale.getDefault()); 
      mainList.clear(); 
      if (charText.length() == 0) { 
       mainList.addAll(arraylist); 
      } else { 
       for (YourObject wp : arraylist) { 
        if (wp.getName().toLowerCase(Locale.getDefault()).contains(charText) || 
          wp.getKey().contains(charText)) { 
         mainList.add(wp); 
        } 
       } 
      } 
      notifyDataSetChanged(); 
     } 

и активность или фрагмент при использовании этого адаптера

edittext.addTextChangedListener(new TextWatcher() { 
      @Override 
      public void beforeTextChanged(CharSequence s, int start, int count, int after) { 

      } 

      @Override 
      public void onTextChanged(CharSequence s, int start, int before, int count) { 

      } 

      @Override 
      public void afterTextChanged(Editable s) { 
       String text = mSearch.getText().toString().toLowerCase(Locale.getDefault()); 
       adaper.filter(text); 
      } 
     }); 
+0

Где находится основной список переменная исходит? –

+0

от конструктора вы передаете свой список элементов вашего конструктора из активности/фрагмента –

+0

Я все еще не понимаю. Класс не имеет имени с именем mainList. Если это то, где я передал все доступные элементы, и я его очистил, то как мне его восстановить позже? Я как-то не получаю никакого контекста здесь ... Тогда что будет уведомлятьDataSetChanged()? Как он находит mainList (опять же, я думаю, что mainList не существует в ArrayAdapter ...) –

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