RecyclerView上的过滤器仅显示列表中的第一个值

时间:2018-12-05 12:40:10

标签: android android-recyclerview filtering android-adapter

我有一个RecyclerView填充的RoomDatabase,并创建了SearchView来过滤结果(如果我想从中提取一组特定的值)。 问题如下:

  • 仅当我单击搜索按钮时才填充列表,而不是在打开视图时填充列表。
  • 使用搜索栏时,无论我写什么,只要它是列表中的一个元素,它都只会在第一个位置显示该元素。如果我键入的内容不属于列表,则该列表将显示为空白,因此至少可以正常工作。

这是适配器的代码:

 public class AbonamenteAdapter2 extends RecyclerView.Adapter<AbonamenteAdapter2.AbonamenteHolder2> implements Filterable {

    private List<Abonamente> abonamente;
    private List<Abonamente> abonamenteFiltered;
   private OnItemClickClickListener listener;

    public void setAbonamente(final List<Abonamente> abonamente) {
        //this.context = (Context) context;
        if (this.abonamente == null) {
            this.abonamente = abonamente;
            this.abonamenteFiltered = abonamente;
            notifyItemChanged(0, abonamenteFiltered.size());
        } else {
            final DiffUtil.DiffResult result = DiffUtil.calculateDiff(new DiffUtil.Callback() {
                @Override
                public int getOldListSize() {
                    return AbonamenteAdapter2.this.abonamente.size();
                }

                @Override
                public int getNewListSize() {
                    return abonamente.size();
                }

                @Override
                public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {
                    return AbonamenteAdapter2.this.abonamente.get(oldItemPosition).getTreatPicked() ==
                            abonamente.get(newItemPosition).getTreatPicked();
                }

                @Override
                public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {

                    Abonamente newAbonament = AbonamenteAdapter2.this.abonamente.get(oldItemPosition);
                    Abonamente oldAbonament = abonamente.get(newItemPosition);

                    return newAbonament.getTreatPicked() == oldAbonament.getTreatPicked();
                }
            });
            this.abonamente = abonamente;
            this.abonamenteFiltered = abonamente;
            result.dispatchUpdatesTo(this);
        }
    }

    @NonNull
    @Override
    public AbonamenteHolder2 onCreateViewHolder (@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.list_item, parent, false);
        return new AbonamenteHolder2(view);
    }

    @Override
    public void onBindViewHolder(@NonNull AbonamenteHolder2 holder2, int position) {
        Abonamente currentAb = abonamente.get(position);
        holder2.treatChosen.setText(currentAb.getTreatPicked());

        //holder2.treatChosen.setText(abonamente.get(position).getTreatPicked());
        //holder2.treatDisplay = abonamente.getTreatDisplay();
        //holder2.treatPrice = abonamente.getPrice();
    }

    @Override
    public int getItemCount() {
        if(abonamente != null) {
            return abonamenteFiltered.size();
        } else {
            return 0;
        }
    }

    @Override
    public Filter getFilter() {
        return new Filter() {
            @Override
            protected FilterResults performFiltering(CharSequence charSequence) {
                String charString = charSequence.toString();
                if (charString.isEmpty()) {
                    abonamenteFiltered = abonamente;
                } else {
                    List<Abonamente> filteredList = new ArrayList<>();
                    for (Abonamente abonament : abonamente) {
                        if (abonament.getTreatPicked().toLowerCase()
                                .contains(charString.toLowerCase())) {
                            filteredList.add(abonament);
                        }
                    }
                    abonamenteFiltered = filteredList;
                }

                FilterResults filterResults = new FilterResults();
                filterResults.values = abonamenteFiltered;
                return filterResults;
            }

            @Override
            protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
                abonamenteFiltered = (ArrayList<Abonamente>) filterResults.values;
                notifyDataSetChanged();
            }
        };
    }


    public class AbonamenteHolder2 extends RecyclerView.ViewHolder {
        TextView treatChosen;


        public AbonamenteHolder2(View view) {
            super(view);
            treatChosen = view.findViewById(R.id.element);
            view.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    int position = getAdapterPosition();
                    if(listener != null && position != RecyclerView.NO_POSITION) {
                        listener.onItemClick(abonamente.get(position));
                    }
                }
            });
        }
    }

    public interface OnItemClickClickListener {
        void onItemClick(Abonamente abonamente);
    }

    public void setOnItemClickListener(OnItemClickClickListener listener) {
        this.listener = listener;
    }
}

这是带有列表和搜索栏的活动的代码。它是由其他活动中的按钮按下触发的:

public class RecyclerList extends AppCompatActivity {

    public static final int GET_DATA_LIST = 1;

    private SearchView searchView;
    private AbonamenteAdapter2 adapter;

    private AbonamenteViewModel viewModel;
    private String treatDisplay;
    private int treatPrice;

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

        RecyclerView recyclerView = findViewById(R.id.list);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        recyclerView.setHasFixedSize(true);

        adapter = new AbonamenteAdapter2();
        recyclerView.setAdapter(adapter);

        viewModel = ViewModelProviders.of(this).get(AbonamenteViewModel.class);
        viewModel.getAllEntries().observe(this, new Observer<List<Abonamente>>() {
            @Override
            public void onChanged(@Nullable List<Abonamente> abonamentes) {
                adapter.setAbonamente(abonamentes);
            }
        });

        adapter.setOnItemClickListener(new AbonamenteAdapter2.OnItemClickClickListener() {
            @Override
            public void onItemClick(Abonamente abonamente) {
                Intent intent = new Intent(RecyclerList.this, MainActivity.class);
                intent.putExtra(MainActivity.EXTRA_ID, abonamente.getId());
                intent.putExtra(MainActivity.EXTRA_CHOICE, abonamente.getTreatPicked());
                intent.putExtra(MainActivity.EXTRA_TREAT, abonamente.getTreatDisplay());
                intent.putExtra(MainActivity.EXTRA_PRICE, abonamente.getPrice());
                startActivityForResult(intent, GET_DATA_LIST);
            }
        });
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.search_bar, menu);

        SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
        searchView = (SearchView) menu.findItem(R.id.action_search)
                .getActionView();
        searchView.setSearchableInfo(searchManager
                .getSearchableInfo(getComponentName()));
        searchView.setMaxWidth(Integer.MAX_VALUE);

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

            @Override
            public boolean onQueryTextChange(String query) {
                adapter.getFilter().filter(query);
                return false;
            }
        });
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        if (id == R.id.action_search) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onBackPressed() {
        if(!searchView.isIconified()) {
            searchView.setIconified(true);
            return;
        }
        super.onBackPressed();
    }
}

我花了很长时间来遍历代码,似乎无法弄清楚问题出在哪里。

1 个答案:

答案 0 :(得分:0)

这可能是对您的问题的评论,但是在这里,由于声誉低下,我需要写答案。 您需要使用onBindViewHolder方法将过滤列表设置为模型。

使用

Abonamente currentAb = abonamenteFiltered .get(position);

代替

Abonamente currentAb = abonamente.get(position);