Implementing Search filter Causing problem when pressed backspace

邮差的信 提交于 2020-03-05 03:37:28

问题


I am trying to implement a search filter on complex object data in recyclerview when I type in the Edit text first-time it works properly, but whenever I try to delete characters by pressing back-space in order to modify our search- I am repeatedly failing in this regard. I can only search once !!

        etSearch = (EditText) findViewById(R.id.edittext);

    etSearch.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) {
                myAdapter.filter(s);

        }

        @Override
        public void afterTextChanged(Editable s) {

        }
    });

now the filter code

    public void filter(CharSequence sequence) {
    ArrayList<user> temp = new ArrayList<>();
        if (!TextUtils.isEmpty(sequence)) {
            for (user s : arr) {
                Log.d("users ",s.getName());
                if (s.getName().toLowerCase().contains(sequence)) {
                    temp.add(s);
                }
            }

        } else {
            temp.addAll(arrcopy);
        }
        arr.clear();
        arr.addAll(temp);
        notifyDataSetChanged();
        temp.clear();

}

Whats the issue, I cannot search more than once-any help is appreciated

Here is my Adapter class

    public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyHolder>
{
    Context cxt;
    ArrayList<user> arr;
    ArrayList<user> arrcopy;
    DatabaseReference dref;
    MyAdapter myAdapter;
    public MyAdapter(Context context, ArrayList<user> arrayList)
    {
        cxt = context;
        arr = arrayList;
        arrcopy=new ArrayList<>(arr);
        Log.d("Very start arr",arr.toString());
        notifyDataSetChanged();
        dref = FirebaseDatabase.getInstance().getReference("users");
    }


    @NonNull
    @Override
    public MyHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
        View view = LayoutInflater.from(cxt).inflate(R.layout.item_chatroom,viewGroup,false);
        myAdapter = new MyAdapter(cxt, arr);
        Log.d("Inside MyHolder arr",arr.toString());
        return new MyHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull final MyHolder myHolder,final int i) {

        final String name = arr.get(i).getUsername();
        String pic=arr.get(i).getPic();
        final String mail=arr.get(i).getEmail();
        myHolder.name.setText(name);



        Glide.with(myHolder.profile.getContext())
                .load(pic)
                .into(myHolder.profile);

        myHolder.name.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(cxt,MainActivity.class);
                intent.putExtra("Id",arr.get(i).getId());
                intent.putExtra("Name",arr.get(i).getUsername());
                cxt.startActivity(intent);
            }
        });

        myHolder.info.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                final SweetAlertDialog pDialog = new SweetAlertDialog(cxt, SweetAlertDialog.SUCCESS_TYPE);
                pDialog.setTitleText("User Information e-mail ID");
                pDialog.setContentText("Name: "+name+"\n\n E-mail: "+mail);
                pDialog.setConfirmText("Ok");
                pDialog.show();
            }
        });
    }

    @Override
    public int getItemCount() {
        return arr.size();
    }

    class MyHolder extends RecyclerView.ViewHolder
    {
        TextView name;
        ImageView profile,info;
        public MyHolder(@NonNull View itemView) {
            super(itemView);
            name = itemView.findViewById(R.id.txv);
            profile=itemView.findViewById(R.id.profile);
            info=itemView.findViewById(R.id.profileinfo);
        }
    }

    public void filter(CharSequence sequence) {

        ArrayList<user> temp = new ArrayList<>();
            if (!TextUtils.isEmpty(sequence)) {
                for (user s : arr) {
                    if (s.getName().toLowerCase().contains(sequence)) {
                        temp.add(s);
                    }
                }

            } else {
                temp.addAll(arrcopy);

            }
            arr.clear();
            arr.addAll(temp);

            notifyDataSetChanged();
            temp.clear();

    }

}

回答1:


I assume the arrcopy is the copy of arr like:

ArrayList<User> arrcopy = new ArrayList<>(arr);

If you modify arr, it also change the content of arrcopy. And when no result matches, the arr is empty, so is the arrcopy.

else {
    temp.addAll(arrcopy);
}
arr.clear();
arr.addAll(temp);

Now temp is empty, the arr data you set for adapter is empty, so issues happens. Please try:
In MyAdapter:

Context cxt;
ArrayList<user> arr;
public MyAdapter(Context context) {
    cxt = context;
    dref = FirebaseDatabase.getInstance().getReference("users");
}

public void setData(ArrayList<User> arrayList) {
    arr = arrayList;
    notifyDataSetChanged();
}

Also put the filter() in your activity/fragment:

protected void onCreate(final Bundle savedInstanceState) {
    etSearch = (EditText) findViewById(R.id.edittext);
    etSearch.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            etSearch.requestFocus();
        }
    });
    etSearch.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) {
                filter(etSearch.getText().toString());
        }

        @Override
        public void afterTextChanged(Editable s) {
        }
    });
    etSearch.clearFocus();

    mAdapter = new MyAdapter(this);
    mAdapter.setData(arrayList);
    mRecyclerView.setAdapter(mAdapter);
    ...
}

public void filter(String input) {
    if (!TextUtils.isEmpty(input)) {
        ArrayList<User> temp = new ArrayList<>();
        for (user s : arr) {
            if (s.getName().toLowerCase().contains(input)) {
                temp.add(s);
            }
        }
        mAdapter.setData(temp);
    } else {
        mAdapter.setData(arr);
    }
    mAdapter.notifyDataSetChanged();
}



回答2:


Implement Filterable in your MyAdapter

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyHolder> 
    implements Filterable {
      // change MyObject to user class
      //replace myObjects with arr and reservedList with arrcopy

    Context cxt;
    ArrayList<MyObject> myObjects;
    ArrayList<MyObject> reservedList;
    DatabaseReference dref;


public MyAdapter(Context context, ArrayList<MyObject> arrayList){
        cxt = context;
        myObjects = arrayList;
        reservedList = arrayList
        Log.d("Very start arr",myObjects.toString());
       // notifyDataSetChanged();
        dref = FirebaseDatabase.getInstance().getReference("users");
    }

   //...

@Override
public Filter getFilter() {
    return new Filter() {
        @Override
        protected FilterResults performFiltering(CharSequence charSequence) {
            String charString = charSequence.toString().toLowerCase();
            if (!charString.isEmpty()) {
                List<MyObject> filteredList = new ArrayList<>();
                for (MyObject row : reservedList) {
                    if (row.getName().toLowerCase().contains(charString)){
                        filteredList.add(row);
                    }
                }
                myObjects = filteredList;
            } else {
                myObjects = reservedList;
            }

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

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

and from your activity

etSearch = (EditText) findViewById(R.id.edittext);

etSearch.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) {

      myAdapter.getFilter().filter(s);

    }

    @Override
    public void afterTextChanged(Editable s) {

    }
});


来源:https://stackoverflow.com/questions/56640206/implementing-search-filter-causing-problem-when-pressed-backspace

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!