Android SearchView Фильтр ListView

Я применил поисковый фильтр к моему SearchView в своей панели SherlockAction.

Когда я набираю m, я хочу показать отфильтрованные результаты в представлении списка ниже, которое начинается только с M и так далее. Но теперь он показывает случайные результаты.

введите здесь описание изображениявведите здесь описание изображения

public boolean onQueryTextChange(String newText) {
    Log.i("Nomad", "onQueryTextChange");

    if (TextUtils.isEmpty(newText)) {
        adapter.getFilter().filter("");
        Log.i("Nomad", "onQueryTextChange Empty String");
        placesListView.clearTextFilter();
    } else {
        Log.i("Nomad", "onQueryTextChange " + newText.toString());
        adapter.getFilter().filter(newText.toString());
    }
    return true;
}

public boolean onQueryTextSubmit(String query) {
    Log.i("Nomad", "onQueryTextSubmit");
    return false;
}

public boolean onClose() {
    Log.i("Nomad", "onClose");
    return false;
}

person Harsha M V    schedule 26.12.2012    source источник


Ответы (4)


Поместите это внутрь вашего адаптера:

@Override
public Filter getFilter(){
   return new Filter(){

        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
             constraint = constraint.toString().toLowerCase();
             FilterResults result = new FilterResults();

                if (constraint != null && constraint.toString().length() > 0) {
                  List<String> founded = new ArrayList<String>();
                        for(YourListItemType item: origData){
                            if(item.toString().toLowerCase().contains(constraint)){
                                founded.add(item);
                            }
                    }

                        result.values = founded;
                        result.count = founded.size();
                    }else {
                        result.values = origData;
                        result.count = origData.size();
                    }
            return result;


    }
    @Override
    protected void publishResults(CharSequence constraint, FilterResults results) {
           clear();
           for (String item : (List<String>) results.values) {
                 add(item);
           }
    notifyDataSetChanged();

    }

    }
    }

И это внутри конструктора вашего адаптера

public MyAdapter(Context context, int layoutResourceId, String[] places) {
        super(context, layoutResourceId, data);
        this.context = context;

        this.data = Arrays.asList(places);
        this.origData = new ArrayList<String>(this.data);

 }
person Artem Zelinskiy    schedule 26.12.2012
comment
также я хочу убедиться, что текст, который он фильтрует, относится только к конкретному тексту. Я думаю, что часть вашего кода отсутствует или не отформатирована. не могли бы вы отредактировать свой ответ - person Harsha M V; 26.12.2012
comment
я только что заметил, что вы используете объект массива, но я передаю массив строк в свой адаптер. Итак, все, что мне нужно сделать, это преобразовать объект в строку - person Harsha M V; 26.12.2012
comment
Да, YourListItemType - означает, что вы можете разместить там все, что захотите - person Artem Zelinskiy; 26.12.2012
comment
Неа. мой конструктор похож на этот общедоступный PlacesListAdapter (контекст контекста, ресурс int, места String []) - person Harsha M V; 26.12.2012
comment
this.data = Arrays.asList(места); - это сделает работу. Отредактировал мой ответ - person Artem Zelinskiy; 26.12.2012
comment
Спасибо. я взял ваш код в качестве эталона и реализовал свою версию. Когда я набираю какую-то букву, я получаю сообщение об ошибке. обновил мой код - person Harsha M V; 26.12.2012
comment
откатил вопрос и опубликовал его как новый вопрос. stackoverflow.com/ вопросы/14040364/ - person Harsha M V; 26.12.2012
comment
я получаю эту ошибку Метод add(String) в типе List‹String› неприменим для аргументов (Place) - person Harsha M V; 26.12.2012
comment
Совместное использование Gist с кодом, в котором я также вызываю адаптер gist.github.com/4380422 - person Harsha M V; 26.12.2012
comment
вы должны переопределить add() в методе адаптера с вашим типом - person Artem Zelinskiy; 26.12.2012
comment
Гринси, переопределение add() в arrayadapter не требуется, если вы параметризуете ArrayAdapter с помощью extends ArrayAdapter‹YourItemType›. Кроме того, ваш код плохо работает с удаленными символами в поле фильтра, если вы не удалите все символы. Поэтому я предлагаю сделать для (элемент YourListItemType: origData) вместо для (элемент YourListItemType: данные), поскольку данные изменяются в процессе фильтрации. - person arne.jans; 03.03.2014
comment
@arne.jans спасибо за совет, я немного отредактировал свой код) - person Artem Zelinskiy; 05.03.2014
comment
я хочу использовать этот код, но что такое origData в вашем ответе? - person uniruddh; 11.03.2014
comment
добавить() и очистить(); вызовы методов я не понял. - person Ashish Kudale; 30.11.2016

Получите фильтр от адаптера и отфильтруйте строку, измененную в поле просмотра при изменении запроса.

searchView.setOnQueryTextListener(new OnQueryTextListener() {

        @Override
        public boolean onQueryTextSubmit(String query) {
            return false;
        }

        @Override
        public boolean onQueryTextChange(String newText) {
            getListAdapter().getFilter().filter(newText);
            return true;
        }
    });
person Ivor    schedule 11.03.2015
comment
Что делать, если список очищается, а не фильтруется? - person JorgeAmVF; 14.08.2019
comment
Я думаю, это зависит от эффекта, которого вы хотите достичь, может быть, скрыть его, пока вы не отфильтруете контент, чтобы показать - person Ivor; 16.08.2019
comment
что такое getListAdapter()? у меня есть ArrayList<String> array_list = new ArrayList<>(); ArrayAdapter arrayAdapter = new ArrayAdapter(getContext(), android.R.layout.simple_list_item_1, array_list);, и когда я меняю getListAdapter() на arrayAdapter, я получаю эту ошибку non static method cannot be referenced from a static context очень надеюсь, что вы можете помочь, я искал наш, чтобы сделать простой поиск в списке во фрагменте без успеха - person M J; 17.03.2020

Добавьте элемент в listview_arr, а оставшийся код ниже...:-

    listview_arr = new String[listview_array_location.length];
    listview_arr = listview_array;

    setListAdapter(new bsAdapter(this));


    et.addTextChangedListener(new TextWatcher()
    {
        public void afterTextChanged(Editable s)
        {
              // Abstract Method of TextWatcher Interface.
        }
        public void beforeTextChanged(CharSequence s,
                int start, int count, int after)
        {
            // Abstract Method of TextWatcher Interface.
        }
        public void onTextChanged(CharSequence s,int start, int before, int count)
        {
            /*Log.d("count","count==>"+s.length());

                if(((s.length()-temp)%4)==0)
                {
                    Log.d("in if","if in if"+(s.length()-temp));
                    et.setText(et.getText().toString()+" ");
                    int position = et.getText().toString().length();
                    Editable etext = et.getText();
                    Selection.setSelection(etext, position);
                    temp++;
                }*/

            Log.d("count","count==>"+s);
            textlength = et.getText().length();
            array_sort.clear();
            for (int i = 0; i < listview_array_location.length; i++)
            {
                if (textlength <= listview_array_location[i].length())
                {
                    if(et.getText().toString().equalsIgnoreCase((String)listview_array_location[i].subSequence(0,textlength)))
                    {
                        array_sort.add(listview_array[i]);
                    }
                  }
            }
            AppendList(array_sort);
        }
    });
}

public void AppendList(ArrayList<String> str)
{
    listview_arr = new String[str.size()];
    listview_arr = str.toArray(listview_arr);

    setListAdapter(new bsAdapter(this));
}

public class bsAdapter extends BaseAdapter
{
    Activity cntx;
    public bsAdapter(Activity context)
    {
        // TODO Auto-generated constructor stub
        this.cntx=context;

    }

    public int getCount()
    {
        // TODO Auto-generated method stub
        return listview_arr.length;
    }

    public Object getItem(int position)
    {
        // TODO Auto-generated method stub
        return listview_arr[position];
    }

    public long getItemId(int position)
    {
        // TODO Auto-generated method stub
        return listview_array.length;
    }

    public View getView(final int position, View convertView, ViewGroup parent)
    {
        View row=null;

        LayoutInflater inflater=cntx.getLayoutInflater();
        row=inflater.inflate(R.layout.search_list_item, null);

        TextView tv=(TextView)row.findViewById(R.id.title);
        Button Btn01=(Button)row.findViewById(R.id.Btn01);
        Button Btn02=(Button)row.findViewById(R.id.Btn02);

        tv.setText(listview_arr[position]);

        Btn01.setOnClickListener(new OnClickListener()
        {
            public void onClick(View v)
            {
                Toast.makeText(SearchUser.this, "Button 1 "+listview_arr[position], Toast.LENGTH_SHORT).show();
                  int color = PreferenceManager.getDefaultSharedPreferences(
                          SearchUser.this).getInt(COLOR_PREFERENCE_KEY, Color.WHITE);
                  new ColorPickerDialog(SearchUser.this, SearchUser.this, color).show();
            }
         });

        Btn02.setOnClickListener(new OnClickListener()
        {
            public void onClick(View v) 
            {
                Toast.makeText(SearchUser.this, "Button 2 "+listview_arr[position], Toast.LENGTH_SHORT).show();
            }
         });

    return row;
    }
}
person Mehul Ranpara    schedule 26.12.2012

вы можете просто просмотреть этот пример. это очень легко интегрировать в ваше приложение

Вот логика с массивом и addTextChangedListener для EditText

person Ram kiran    schedule 26.12.2012