Мой пользовательский вид поиска работает некорректно, не отображается исходный список, когда ввод поиска равен нулю

#android #listview #android-arrayadapter #android-listadapter

#Android #listview #android-arrayadapter #android-listadapter

Вопрос:

Я пытаюсь реализовать пользовательский счетчик с возможностью поиска в своей деятельности, но что-то не так в коде, и я не могу его найти. Посмотрите на скриншоты ниже, чтобы понять мою проблему.

snap1 Вот исходное представление списка с тремя элементами, и фильтр поиска еще не добавлен

snap2 Вот список после фильтра поиска

snap3 Вот список после удаления поиска.

Итак, как вы можете видеть на третьем снимке экрана, в listview не отображаются все три элемента после очистки фильтра поиска. Можете ли вы увидеть, какую ошибку я допускаю в своем коде?

ListAdapter.java

 public class ListAdapter extends ArrayAdapter<SpinnerItem> {

    private List<SpinnerItem> items;
    private Context context;
    private Filter filter;
    public ListAdapter(@NonNull Context context, int resource, List<SpinnerItem> items) {
        super(context, resource);
        this.context = context;
        this.items = items;
        this.filter = new CustomItemsFilter();
    }

    @Nullable
    @Override
    public SpinnerItem getItem(int position) {
        return items.get(position);
    }

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

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

        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View rootView = inflater.inflate(R.layout.list_item,parent,false);
        TextView textView = rootView.findViewById(R.id.itemTitle);
        TextView textView1 = rootView.findViewById(R.id.itemSubTitle);
        TextView textView2 = rootView.findViewById(R.id.itemSign);

        textView.setText(items.get(position).getTitle());
        textView1.setText(items.get(position).getSubTitle());
        textView2.setText(items.get(position).getSign());
        return rootView;
    }

    @NonNull
    @Override
    public Filter getFilter() {

        if(filter == null) {
            filter = new CustomItemsFilter();
        }
        return filter;
    }

    private class CustomItemsFilter extends Filter {

        @Override
        protected FilterResults performFiltering(CharSequence constraint) {

            FilterResults filterResults = new FilterResults();

            if(constraint != null amp;amp; constraint.toString().length() > 0) {
                constraint = constraint.toString().toLowerCase();
                List<SpinnerItem> allItems = new ArrayList<SpinnerItem>();
                List<SpinnerItem> filterItems = new ArrayList<SpinnerItem>();
                synchronized (this) {
                    allItems.addAll(items);
                }
                for (int i = 0; i < allItems.size();   i) {
                    SpinnerItem item = allItems.get(i);
                    if(item.getTitle().contains(constraint) || item.getSubTitle().contains(constraint) || item.getSign().contains(constraint)) {
                        filterItems.add(item);
                    }
                }
                filterResults.count = filterItems.size();
                filterResults.values = filterItems;
            }
            else {
                synchronized (this) {
                    filterResults.values = items;
                    filterResults.count = items.size();
                }
            }
            return filterResults;
        }

        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {

            if(results.count > 0) {
                items = (List<SpinnerItem>) results.values;
                notifyDataSetChanged();
            }
        }

    }
}
 

SpinnerDialog.java

 public class SpinnerDiaglog implements SearchView.OnCloseListener, SearchView.OnQueryTextListener{

     private List<SpinnerItem> items;
     private OnSpinnerItemClick onSpinnerItemClick;
     private Activity context;
     private SearchView searchView;
     private DialogInterface.OnClickListener onClickListener;
     private ListAdapter adapter;
     private OnSearchTextChanged onSearchTextChanged;
     private ListView listView;
     private AlertDialog dialog;

    public SpinnerDiaglog() {
    }

    public SpinnerDiaglog(Activity context, List<SpinnerItem> items) {
         this.context = context;
         this.items = items;
     }

    public void onCreateDialog() {
        View rootView = context.getLayoutInflater().inflate(R.layout.spinner_dialog,null);
        //setData(rootView);
        AlertDialog.Builder alertDialog = new AlertDialog.Builder(context);
        alertDialog.setView(rootView);
        alertDialog.setPositiveButton("CLOSE",onClickListener);
        alertDialog.setTitle("Select Item");

        SearchManager searchManager = (SearchManager) context.getSystemService(Context
                .SEARCH_SERVICE);

        searchView = rootView.findViewById(R.id.search);
        searchView.setSearchableInfo(searchManager.getSearchableInfo(context.getComponentName()));
        searchView.setOnQueryTextListener(this);
        searchView.setOnCloseListener(this);
        searchView.setIconifiedByDefault(false);
        searchView.clearFocus();

        listView = rootView.findViewById(R.id.listItems);
        adapter = new ListAdapter(context,R.layout.list_item,items);
        listView.setAdapter(adapter);

        dialog = alertDialog.create();
        dialog.show();

        listView.setOnItemClickListener((parent, view, position, id) -> {
            onSpinnerItemClick.onClick(adapter.getItem(position),position);
            dialog.dismiss();
        });
    }

    public void setOnSpinnerItemClickListener(OnSpinnerItemClick onSpinnerItemClick) {
        this.onSpinnerItemClick = onSpinnerItemClick;
    }
    public void setOnSearchTextChangedListener(OnSearchTextChanged onSearchTextChanged) {
        this.onSearchTextChanged = onSearchTextChanged;
    }


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

    @Override
    public boolean onQueryTextChange(String newText) {

         if(TextUtils.isEmpty(newText)) {
             ((ListAdapter) listView.getAdapter()).getFilter().filter(null);
         }
         else {
             ((ListAdapter) listView.getAdapter()).getFilter().filter(newText);
         }
        if (null != onSearchTextChanged) {
            onSearchTextChanged.onSearchTextChanged(newText);
        }
        return true;
    }

    public interface OnSpinnerItemClick {

        void onClick(SpinnerItem item, int position);
    }

    public interface OnSearchTextChanged {
        void onSearchTextChanged(String strText);
    }


    @Override
    public boolean onClose() {
        return false;
    }


}
 

MainActivity.java

 public class MainActivity2 extends AppCompatActivity {

    private SpinnerDiaglog spinnerDiaglog;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);

        Button button = findViewById(R.id.show);

        List<SpinnerItem> items = new ArrayList<>();
        items.add(new SpinnerItemImp("Title","subTitle","sign"));
        items.add(new SpinnerItemImp("aitle","subTitle","sign"));
        items.add(new SpinnerItemImp("Tiastle","subTitle","sign"));
        button.setOnClickListener(v -> {

            spinnerDiaglog = new SpinnerDiaglog(MainActivity2.this,items);
            spinnerDiaglog.onCreateDialog();

        });
    }
}
 

SpinnerItemImp.java

 public class SpinnerItemImp implements SpinnerItem {

    private String title;
    private String subTitle;
    private String sign;

    public SpinnerItemImp(String title, String subTitle, String sign) {
        this.title = title;
        this.subTitle = subTitle;
        this.sign = sign;
    }

    @Override
    public String getTitle() {
        return title;
    }

    @Override
    public String getSubTitle() {
        return subTitle;
    }

    @Override
    public String getSign() {
        return sign;
    }
}
 

Ответ №1:

Вы сохраняете единый список, items который изменяется при первом применении фильтра. Итак, при следующем фильтре вы фактически фильтруете из отфильтрованного списка, а не из фактического списка.

Вам необходимо вести полный список отдельно и применять к нему фильтр, а не в отфильтрованном списке. Ниже приведен пример:

 public class ListAdapter extends ArrayAdapter<SpinnerItem> {
    private List<SpinnerItem> items;
    private List<SpinnerItem> allItems;
    private Context context;
    private Filter filter;
    public ListAdapter(@NonNull Context context, int resource, List<SpinnerItem> items) {
        super(context, resource);
        this.context = context;
        this.items = items;
        this.filter = new CustomItemsFilter();
        allItems=new ArrayList<>(items);
    }

    @Override
    public SpinnerItem getItem(int position) {
        return items.get(position);
    }

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

    @NonNull
    @Override
    public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View rootView = inflater.inflate(R.layout.list_item,parent,false);
        return rootView;
    }

    @NonNull
    @Override
    public Filter getFilter() {
        if(filter == null) {
            filter = new CustomItemsFilter();
        }
        return filter;
    }

    private class CustomItemsFilter extends Filter {
        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            items.clear();
            FilterResults filterResults = new FilterResults();
            constraint = constraint.toString().trim().toLowerCase();
            if (constraint.length() > 0) {
                for (int i = 0; i < allItems.size();   i) {
                    SpinnerItem item = allItems.get(i);
                    if (item.getTitle().contains(constraint) || item.getSubTitle().contains(constraint) || item.getSign().contains(constraint)) {
                        items.add(item);
                    }
                }
            } else {
                items.addAll(allItems);
            }
            filterResults.values = items;
            filterResults.count = items.size();
            return filterResults;
        }

        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {
           
                items = (List<SpinnerItem>) results.values;
                notifyDataSetChanged();
           
        }
    }
}