RecyclerView列表搜索(过滤)EditText问题

Posted

技术标签:

【中文标题】RecyclerView列表搜索(过滤)EditText问题【英文标题】:RecyclerView list search (filter) EditText problem 【发布时间】:2021-12-03 18:27:07 【问题描述】:

我想在我的recyclerview列表中添加一个搜索功能,我通过查看教科书尝试了互联网上的代码,它工作正常但是如果你删除edittext中的字母列表不会返回,它只是删除列表。

示例:如果我在edittext中输入'' I 12345 '',其余的将被删除,只保留'' I 12345 '',但如果我在edittext中删除文本,列表将不会返回。

请帮忙修复!

这里是我的所有代码:

MainActivity java:

public class MainActivity extends AppCompatActivity 

    RecyclerViewAdapter recyclerViewAdapter;

    RecyclerView recyclerView;

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

        recyclerView = findViewById(R.id.recyclerview1);

        //here start search code


        EditText editText = findViewById(R.id.izlash_edittext);
        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) 
                filter(s.toString());
            
        );


        //here end search code

        recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));

        ArrayList<Item> items = new ArrayList<>();

        items.add(new Item("start", R.drawable.start));
        items.add(new Item("end", R.drawable.end));

        recyclerView.setAdapter(recyclerViewAdapter);

    

        //here start search code
    private void filter(String title) 
        ArrayList<Item> filteredList = new ArrayList<>();

        for (Item item : recyclerViewAdapter.items) 
            if (item.title.toLowerCase().contains(title.toLowerCase())) 
                filteredList.add(item);
            

            recyclerViewAdapter.filterList(filteredList);
        
    

        //here end search code


RecyclerViewAdapter java:

public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> 

    ArrayList<Item> items;
    ItemClickListener itemClickListener;

    public RecyclerViewAdapter(ArrayList<Item> items, ItemClickListener itemClickListener) 
        this.items = items;
        this.itemClickListener = itemClickListener;
    

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) 

        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.single_item, parent, false);

        return new ViewHolder(view);
    

    @Override
    public void onBindViewHolder(@NonNull RecyclerViewAdapter.ViewHolder holder, int position) 

        Item item = items.get(position);

        holder.title.setText(item.title);
        holder.imageView.setImageResource(item.image);

        holder.itemView.setOnClickListener(view -> 
            itemClickListener.onClick(item);
        );
    

    @Override
    public int getItemCount() 
        return items.size();
    

    //here start search code

    public void filterList(ArrayList<Item> filteredList) 
        items = filteredList;
        notifyDataSetChanged();
    

    //here end search code

    public interface ItemClickListener 
        void onClick(Item item);
    

    class ViewHolder extends RecyclerView.ViewHolder 

        TextView title;
        ImageView imageView;

        public ViewHolder(@NonNull View itemView) 
            super(itemView);

            title = itemView.findViewById(R.id.textView1);
            imageView = itemView.findViewById(R.id.imageview1);
        

    

项目 java:

public class Item 

    String title;
    int image;
    String qisqaMalumot;
    String uzunMalumot;

    public Item(String title, int image, String qisqaMalumot, String uzunMalumot) 
        this.title = title;
        this.image = image;
        this.qisqaMalumot = qisqaMalumot;
        this.uzunMalumot = uzunMalumot;
    

请帮帮我。

【问题讨论】:

将 recyclerViewAdapter.items 替换为您的原始项目列表,因为您正在循环遍历已过滤的列表 对不起,请给我看看代码吗?我应该在哪里改变,谢谢。 在 oncreate 之外声明您的项目列表(移动 ArrayList items = new ArrayList() )并在过滤器函数内部将 recyclerViewAdapter.items 替换为 items 很抱歉你解释得这么好,但我不能,因为我没有足够的知识,你能改变我的代码吗?请,谢谢。 我们都去过那里,你看你是如何在 MainActivity java move "ArrayList items = new ArrayList();" 的顶部有“ RecyclerView recyclerView;”在那里,并用这个“for(Item item:items)”替换“for(Item item:recyclerViewAdapter.items)”额外:现在为什么我们把它移出来是因为范围请阅读更多关于范围的信息,当你使用一个变量像这种称为声明变量的“int x = 5”。现在还有其他方法可以解决你的问题,但我让你变得简单,只需做我所说的小改动,祝你好运 【参考方案1】:
 for (Item item : recyclerViewAdapter.items) 
        if (item.title.toLowerCase().contains(title.toLowerCase())) 
            filteredList.add(item);
        

当您在recyclerViewAdapter.items 中搜索时,recyclerview 被新数据替换,旧数据消失了。

首先制作全局列表ArrayList&lt;Item&gt; items = new ArrayList&lt;&gt;();

public class MainActivity extends AppCompatActivity 

RecyclerViewAdapter recyclerViewAdapter;
ArrayList<Item> items = new ArrayList<>();
RecyclerView recyclerView;

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

在你的 for 循环中第二次替换 items

  for (Item item : items) 
        if (item.title.toLowerCase().contains(title.toLowerCase())) 
            filteredList.add(item);
        

完成了!

【讨论】:

【参考方案2】:

首先您需要在您的适配器中实现 Filterable。然后您需要在 listadapter 中保留一个过滤的项目,以便您可以恢复到它的旧状态。当您在主活动中登录以从 edittext 查询时,适配器可以通过这种方式更改并恢复到其旧状态。如果你根据自己编辑代码,它会顺利运行。

      public class BulletinAdapter extends RecyclerView.Adapter<BulletinAdapter.BulletinVHolder> implements Filterable 

    private Context context;
    private List<EventResponseItem> eventsItemList;
    private List<EventResponseItem> filteredList;

    public BulletinAdapter(Context context, List<EventResponseItem> eaItemList) 
        this.context = context;
        this.filteredList = eaItemList;
    

    @NonNull
    @Override
    public BulletinVHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) 
        return new BulletinVHolder(RowNewaddBinding.inflate(LayoutInflater.from(context), parent, false));
    

    @Override
    public void onBindViewHolder(@NonNull BulletinVHolder holder, int position) 
        EventResponseItem eaItem = filteredList.get(position);

        if (eaItem != null) 
            holder.bind.rowNewMatchId.setText(String.valueOf(eaItem.getEid()));
        

    

    @Override
    public int getItemCount() 
        if (filteredList != null && filteredList.size() > 0) 
            return filteredList.size();
         else 
            return 0;
        
    

    @Override
    public int getItemViewType(int position) 
        return super.getItemViewType(position);
    

    @Override
    public Filter getFilter() 
        return new Filter() 
            @Override
            protected FilterResults performFiltering(CharSequence constraint) 
                String charString = constraint.toString();
                if (constraint.length() == 0) 
                    filteredList = eventsItemList;
                 else 
                    List<EventResponseItem> filterList = new ArrayList<>();
                    for (EventResponseItem modelMovie : eventsItemList) 
                        if (modelMovie.getEprt().get(0).getPn().toLowerCase().contains(charString) | modelMovie.getEprt().get(1).getPn().toLowerCase().contains(charString)) 
                            filterList.add(modelMovie);
                        
                    
                    filteredList = filterList;
                
                FilterResults filterResults = new FilterResults();
                filterResults.values = filteredList;
                return filterResults;

            

            @Override
            protected void publishResults(CharSequence constraint, FilterResults results) 
                filteredList = (List<EventResponseItem>) results.values;
                notifyDataSetChanged();
            
        ;
    

    class BulletinVHolder extends RecyclerView.ViewHolder 

        private RowNewaddBinding bind;

        public BulletinVHolder(@NonNull RowNewaddBinding bind) 
            super(bind.getRoot());
            this.bind = bind;
        
    

MainActivity.class..

private List<EventResponseItem> eventsItemList; //set list data
        private BulletinAdapter bulletinAdapter; //recyclerview set adapter...(data and layoutmanager)
       bulletinAdapter = new BulletinAdapter(MatchAddNew.this,eventsItemList);
                        bind.matchAddNewRecyclerView.setLayoutManager(new LinearLayoutManager(MatchAddNew.this));
                        bind.matchAddNewRecyclerView.setAdapter(bulletinAdapter); 
            search(bind.searchViewNewMatch); //viewBinding your edittext...
            
            private void search(SearchView searchView) 
                    searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() 
                        @Override
                        public boolean onQueryTextSubmit(String s) 
                            return false;
                        
            
                        @Override
                        public boolean onQueryTextChange(String s) 
                            if (bulletinAdapter != null) 
                                bulletinAdapter.getFilter().filter(s.toLowerCase());
                            
            
                            return true;
                        
                    );

            

【讨论】:

以上是关于RecyclerView列表搜索(过滤)EditText问题的主要内容,如果未能解决你的问题,请参考以下文章

RecyclerView(自定义适配器)不刷新搜索列表

按下键盘上的复选标记键时,可使用 RecyclerView 进行过滤

如何在 Recyclerview 中正确使用 DiffUtil 更新数组列表?

搜索过滤器后如何更新android RecyclerView项目?

使用 Room 和 RecyclerView 在 SearchView 中添加过滤器

可过滤在 Recyclerview 中无法按预期工作