简体   繁体   中英

Showing wrong data when filtered RecyclerView item is clicked

I have a RecyclerView with search bar in my android app. When I search in it and click on an item, it shows wrong data.

I know why it happens but I don't know how to fix it. I have tried many things but still I have the problem.

Here is the code of my Adapter.

RecyclerView.Adapter<hisAdapter.hisViewHolder> {
    private ArrayList<hisItem> mhislist;
    public onItemClickListener mListener;

    public  interface onItemClickListener {
        void onItemClick(int position);
    }

    public void  setOnitemClickLIstener(onItemClickListener lIstener) {
        mListener = lIstener;
    }

    public class hisViewHolder extends RecyclerView.ViewHolder {
        public TextView mTextView1;
        public TextView mTextView2;
        public TextView card_num;

        public hisViewHolder(View itemView) {
            super(itemView);
            mTextView1 = itemView.findViewById(R.id.textView1);
            mTextView2 = itemView.findViewById(R.id.textView2);
            card_num = itemView.findViewById(R.id.number);

            itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                   if (mListener != null) {
                       int position = getAdapterPosition();
                       if (position != RecyclerView.NO_POSITION){
                           mListener.onItemClick(position);
                       }
                    }
                }
            });
        }
    }

    public hisAdapter(ArrayList<hisItem> hisList){
         mhislist = hisList;
    }

    @Override
    public hisViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
      View v = 
      LayoutInflater.from(parent.getContext()).inflate(R.layout.his_item, parent, false);
      hisViewHolder hvh = new hisViewHolder(v);

      return hvh;
    }

    @Override
    public void onBindViewHolder(hisViewHolder holder, int position) {
        hisItem currentItem = mhislist.get(position);
        holder.mTextView1.setText(currentItem.getText1());
        holder.mTextView2.setText(currentItem.getText2());
        holder.card_num.setText(currentItem.getText3());
    }

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

    public void filterList(ArrayList<hisItem> filteredList){
        mhislist = filteredList;
        notifyDataSetChanged();
    }
}

This is the MainActivity where I have a search functionality code and click handler.

editTextt.addTextChangedListener(new TextWatcher() {
       @Override
       public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { }

        @Override
        public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { }

        @Override
        public void afterTextChanged(Editable editable) {
            filter(editable.toString());
        }
    });
}

public void filter(String text) {
    ArrayList<hisItem> filteredList = new ArrayList<>();

    for (hisItem item : hisList) {
        if (item.getText1().toLowerCase().contains(text.toLowerCase())) {
            filteredList.add(item);
        }
    }

    mAdapter.filterList(filteredList);
}

@Override
public void onItemClick(int position) {
    Intent intent = new Intent(this, singleActivity.class);
    hisItem clickeditem = hisList.get(position);
    String pos = String.valueOf(position);
    intent.putExtra(CARD_NUM ,pos );
    intent.putExtra(HEAD_LINE,clickeditem.getText1());
    intent.putExtra(REAL_NUM,clickeditem.getText3());
    startActivity(intent);
}

Please let me know if there's anything I need to add in my question. I am available to provide those. Thanks.

You can solve the issue in two different ways. You might consider changing the function in your MainActivity . Because what you are doing in your onItemClick function is wrong. You are getting the item from the hisList when some items from this hisList are already filtered out. So you need to get the items from your filteredList in this case. This can be easily achieved by declaring the filteredList as a global variable in your MainActivity .

// Declaring the filteredList as a public variable that can be accessed from anywhere in this class.
public ArrayList<String> filteredList = new ArrayList<>();

@Override
public void onItemClick(int position) {
    Intent intent = new Intent(this, singleActivity.class);

    // Get the item from the filteredList which is the updated one.
    hisItem clickeditem = filteredList.get(position);

    String pos = String.valueOf(position);
    intent.putExtra(CARD_NUM ,pos );
    intent.putExtra(HEAD_LINE,clickeditem.getText1());
    intent.putExtra(REAL_NUM,clickeditem.getText3());
    startActivity(intent);
}

However, the second way is to integrate the onClick behaviour in your adapter. I prefer this as this is simple and this is not prone to error. It will be always handling the list passed to the adapter. So there is no other headache.

itemView.setOnClickListener(new View.OnClickListener() {

    @Override
    public void onClick(View view) {
        int position = getAdapterPosition();

        Intent intent = new Intent(context, singleActivity.class);
        hisItem clickeditem = mhislist.get(position);
        String pos = String.valueOf(position);
        intent.putExtra("CARD_NUMBER", pos);
        intent.putExtra("HEAD_LINE", clickeditem.getText1());
        intent.putExtra("REAL_NUMBER", clickeditem.getText3());
        startActivity(intent);
    }
});

Hope that helps.

Use this code it will solve your problem definitely!!

private ArrayList<Employee> filteredList = new ArrayList<Employee>();
    private void filter(String text) {
      filteredList.clear();
      for (Employee item : mEmployeeList) {
        if (item.getVehicle_number().toLowerCase().contains(text.toLowerCase())) {
          filteredList.add(item);
        }
      }
      myadapter.filterList(filteredList);
    }
    
    @Override
    public void onItemClick(int position) {
      Intent ediIntent = new Intent(this, Edit_Activity.class);
      if(filteredList.size() > 0) {
        Employee clickedItem = filteredList.get(position);
       } else {
          Employee clickedItem = mEmployeeList.get(position);
       }
      ...
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM