getFilter () в пользовательском ArrayAdapter не работает - PullRequest
0 голосов
/ 10 ноября 2018

Я использую Custom ArrayAdapter для хранения пользовательской информации, например, sammy, robert, lizie - это каждый объект User, и я использую тип User ArrayList для хранения всех пользователей.объекты в ArrayList .

И поскольку это не строка или int (ArrayList), по умолчанию getFilter не работает, и я провел свое исследование, но это действительно сбивает с толку, как getFilter метод работает, поэтому я могу изменить себя.

Я хочу реализовать поиск на основе свойства name из User class

Я знаю, что у меня естьреализовать интерфейс Filterable в моем классе CustomAdapter , но getFilter действительно не интуитивно понятен.

Вот мой CustomAdapter

class CustomArrayAdapter extends ArrayAdapter<User>  implements Filterable {


    CustomArrayAdapter(@NonNull Context context, ArrayList<User> users) {
        super(context, 0, users);
    }

    @NonNull
    @Override
    public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {

        User innserUser = getItem(position);

        if (convertView == null){

            convertView = LayoutInflater.from(getContext()).inflate(R.layout.row_layout, parent, false);

        }

        TextView username = (TextView) convertView.findViewById(R.id.userNameContact);
        TextView userNumber = (TextView) convertView.findViewById(R.id.userNumberContact);
        ImageView userImage = (ImageView) convertView.findViewById(R.id.userImageContact);

        try {
            if(innserUser != null) {
                username.setText(innserUser.name);
                userNumber.setText(innserUser.number);
                userImage.setImageBitmap(innserUser.imageBitmap);
            }
        }catch (Exception e){
            e.printStackTrace();
        }

        return convertView;

    }


}

и вот пользовательский класс здесь ничего особенного

import android.graphics.Bitmap;

public class User {

    String id, name, number;
    Bitmap imageBitmap;

    User(String id, String name, String number, Bitmap imageBitmap){

        this.id = id;
        this.name = name;
        this.number = number;
        this.imageBitmap = imageBitmap;

    }
}

Я связал множество вариантов getFilter от многихтемы, но ни один из них не работает для меня, и один с хорошими объяснениями для BaseAdapter, а не для ArrayAdapter

Я пробовал этот вопрос , и я пробовал этот вопрос но у меня не работает.

Я новичок в разработке для Androidполе, и это кажется особенно не интуитивным.Любые предложения будут очень признательны, спасибо.

РЕДАКТИРОВАТЬ 1 : После ответа jitesh mohite , Спасибо за повтор jitesh mohite

class CustomArrayAdapter extends ArrayAdapter<User>  implements Filterable {


    ArrayList<User> users;

    CustomArrayAdapter(@NonNull Context context, ArrayList<User> users) {
        super(context, 0, users);
        this.users = users;
    }

    @NonNull
    @Override
    public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {

        User innserUser = getItem(position);

        if (convertView == null){

            convertView = LayoutInflater.from(getContext()).inflate(R.layout.row_layout, parent, false);

        }

        TextView username = (TextView) convertView.findViewById(R.id.userNameContact);
        TextView userNumber = (TextView) convertView.findViewById(R.id.userNumberContact);
        ImageView userImage = (ImageView) convertView.findViewById(R.id.userImageContact);

        try {
            if(innserUser != null) {
                username.setText(innserUser.name);
                userNumber.setText(innserUser.number);
                userImage.setImageBitmap(innserUser.imageBitmap);
            }
        }catch (Exception e){
            e.printStackTrace();
        }

        return convertView;

    }


    Filter myFilter = new Filter() {
        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            FilterResults filterResults = new FilterResults();
            ArrayList<User> tempList=new ArrayList<User>();
            // Add the filter code here
            if(constraint != null && users != null) {
                int length= users.size();
                int i=0;
                while(i<length){
                    User item= users.get(i);
                    //do whatever you wanna do here
                    //adding result set output array

                    //item.name is user.name cause i want to search on name
                    if(item.name.toLowerCase().contains(constraint.toString().toLowerCase()) ) { // Add check here, and fill the tempList which shows as a result

                        tempList.add(item);
                    }

                    i++;
                }
                //following two lines is very important
                //as publish result can only take FilterResults users
                filterResults.values = tempList;
                filterResults.count = tempList.size();
            }
            return filterResults;
        }

        @SuppressWarnings("unchecked")
        @Override
        protected void publishResults(CharSequence contraint, FilterResults results) {
            users = (ArrayList<User>) results.values;
            if (results.count > 0) {
                notifyDataSetChanged();
            } else {
                notifyDataSetInvalidated();
            }
        }
    };

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


}

поиск не работает на customadapter, но я думаю, что я делаю что-то не так.

здесь я что-то набираю в строке поиска, но фильтрация не происходит

enter image description here

, и если вы хотите увидеть код панели поиска, то ничего особенного простообычный

@Override
public boolean onCreateOptionsMenu(Menu menu) {

    MenuInflater inflater = getMenuInflater();

    inflater.inflate(R.menu.search_box, menu);

    MenuItem item = menu.findItem(R.id.app_bar_search);

    SearchView searchView = (SearchView)item.getActionView();

    searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
        @Override
        public boolean onQueryTextSubmit(String query) {
            return false;
        }

        @Override
        public boolean onQueryTextChange(String newText) {

            customArrayAdapter.getFilter().filter(newText);

            return false;
        }
    });


    return true;



}

Ответы [ 2 ]

0 голосов
/ 10 ноября 2018
Встроенный в

ArrayAdapter Filter использует возврат toString() из класса модели (т. Е. Его параметр типа) для выполнения фильтрационных сравнений. Вам не обязательно нужна пользовательская реализация Filter, если вы можете переопределить метод User toString() для возврата того, что вы хотите сравнить, при условии, что его алгоритм фильтрации подходит для вашей ситуации ( см. ниже ). В этом случае:

@Override
public String toString() {
    return name;
}

Чтобы точно понять, что это за алгоритм, фильтрация по умолчанию ArrayAdapter выглядит следующим образом:

Фильтр String сначала преобразуется в нижний регистр. Затем, зацикливаясь на наборе данных, возвращаемое значение toString() каждого значения преобразуется в нижний регистр и проверяется, является ли оно startsWith() фильтром String. Если это так, он добавляется в набор результатов. Если нет, выполняется вторая проверка, в результате чего нижний регистр значения String разделяется на пробел (" "), и каждое значение из этого сравнивается с фильтром, снова используя startsWith(). По сути, сначала проверяется, начинается ли все это с текста фильтра, а затем, при необходимости, проверяется каждое слово.

Если это подходящий фильтр, то это решение является самым простым.

0 голосов
/ 10 ноября 2018
Filter myFilter = new Filter() {
        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
         FilterResults filterResults = new FilterResults();   
         ArrayList<User> tempList=new ArrayList<User>();
         // Add the filter code here
         if(constraint != null && users!=null) {
             int length= users.size();
             int i=0;
                while(i<length){
                    User item= users.get(i);
                    //do whatever you wanna do here
                    //adding result set output array    
                    if()  {  // Add check here, and fill the tempList which shows as a result

                    tempList.add(item);
                  }

                    i++;
                }
                //following two lines is very important
                //as publish result can only take FilterResults users
                filterResults.values = tempList;
                filterResults.count = tempList.size();
          }
          return filterResults;
      }

      @SuppressWarnings("unchecked")
      @Override
      protected void publishResults(CharSequence contraint, FilterResults results) {
          users = (ArrayList<User>) results.values;
          if (results.count > 0) {
           notifyDataSetChanged();
          } else {
              notifyDataSetInvalidated();
          }  
      }
     };

Наконец, переопределите этот метод и верните экземпляр фильтра.

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

Для получения дополнительной информации см. https://gist.github.com/tobiasschuerg/3554252

...