After Filter a RecyclerView item and clicking it gives wrong item

不想你离开。 提交于 2021-02-08 10:12:52

问题


After performing filtering on Recyclerview items that are fetched through json. It's opening the wrong item when I clicked after filtering the list. Suppose A,B,C,D are in my list, and when I filter for B and click on it - it shows the wrong item (like: A,C,D) but not B. How to fix this?

MainActivity.java:

public class exit_Activity extends AppCompatActivity implements MyAdapter.OnItemClickListener {
    String Show_url = "https://retrieve.php";
    public static final String EXTRA_ID = "id";
    public static final String EXTRA_V = "v";
    public static final String EXTRA_Name = "name";
    public static final String EXTRA_t = "in";
    public static final String EXTRA_o = "out";
    public static final String EXTRA_date = "date";
    public static final String EXTRA_yes = "yes";

    RecyclerView removeView;
    private AlertDialog alertDialog;
    ProgressBar progressBar;
    NetworkChangeListerner networkChangeListerner = new NetworkChangeListerner();
    private SwipeRefreshLayout mSwipeRefreshLayout;
    private ArrayList<Employee> mEmployeeList;
    private MyAdapter myadapter;
    TextInputEditText search;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_exit_);
        retrieveData();
        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        ///
        mSwipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.refreshlayout);
        mSwipeRefreshLayout.setColorSchemeResources(R.color.black, R.color.green, R.color.red);
       

        progressBar = (ProgressBar) findViewById(R.id.progressbar);
        Sprite FoldingCube = new Wave();
        progressBar.setIndeterminateDrawable(FoldingCube);
      
        //
        search = findViewById(R.id.search);
        //exit
        removeView = findViewById(R.id.exit_entry);
        removeView.setHasFixedSize(true);
        removeView.setLayoutManager(new LinearLayoutManager(this));
        mEmployeeList = new ArrayList<>();

        myadapter = new MyAdapter(exit_Activity.this, mEmployeeList);
        removeView.setAdapter(myadapter);

        //end


        search.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());
            }
        });
    }

    private void filter(String text) {
        ArrayList<Employee> filteredList = new ArrayList<>();
        for (Employee item : mEmployeeList) {
            if (item.getVehicle_number().toLowerCase().contains(text.toLowerCase())) {
                filteredList.add(item);
            }
        }
       myadapter.filterList(filteredList);
    }


    public void retrieveData() {
        StringRequest request = new StringRequest(Request.Method.POST, Show_url,
                new Response.Listener<String>() {
                    @Override
                    public void onResponse(String response) {
                        mEmployeeList.clear();
                        try {

                            JSONObject jsonObject = new JSONObject(response);
                            String sucess = jsonObject.getString("success");

                            JSONArray jsonArray = jsonObject.getJSONArray("user_data");

                            if (sucess.equals("1")) {

                                for (int i = 0; i < jsonArray.length(); i++) {

                                    JSONObject object = jsonArray.getJSONObject(i);
                                    String id = object.getString("id");
                                    String vehicle_number = object.getString("number");
                                    String driver_name = object.getString("name");
                                    String entry_time = object.getString("time");
                                    String entry_date = object.getString("date");
                                    String exit_time = object.getString("ttime");
                                    String yes = object.getString("yes");
                                    mEmployeeList.add(new Employee(id, number, name, time, date, ttime, yes));
                                }
                               myadapter.notifyDataSetChanged();
                              myadapter.setOnItemClickListener(exit_Activity.this);
                                progressBar.setVisibility(View.GONE);
                                mSwipeRefreshLayout.setRefreshing(false);
                                Toast.makeText(getApplicationContext(), "List Updated", Toast.LENGTH_SHORT).show();
                            }


                        } catch (JSONException e) {
                            e.printStackTrace();
                        }


                    }

                }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                Toast.makeText(exit_Activity.this, error.getMessage(), Toast.LENGTH_LONG).show();
                error.printStackTrace();
            }
        });
        RequestQueue requestQueue = Volley.newRequestQueue(this);
        requestQueue.add(request);

    }

    }
    @Override
    public void onItemClick(int position) {
        Intent ediIntent = new Intent(this, Edit_Activity.class);
        Employee clickedItem = mEmployeeList.get(position);
        ediIntent.putExtra(EXTRA_ID, clickedItem.getId());
        ediIntent.putExtra(EXTRA_V, clickedItem.getnumber());
        ediIntent.putExtra(EXTRA_Name, clickedItem.getname());
        ediIntent.putExtra(EXTRA_date, clickedItem.getdate());
        ediIntent.putExtra(EXTRA_t, clickedItem.gettime());
        ediIntent.putExtra(EXTRA_o, clickedItem.getttime());
        ediIntent.putExtra(EXTRA_yes, clickedItem.getYes());
        startActivity(ediIntent);
    }

Myadapter.class:

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder>{


    private Context mcontext;
    private ArrayList<Employee> marrayListEmployee;
    private OnItemClickListener mListener;

    public interface OnItemClickListener {
        void onItemClick(int position);
    }
    public void setOnItemClickListener(OnItemClickListener listener) {
        mListener = listener;
    }
    public MyAdapter(Context context, ArrayList<Employee> arrayListEmployee) {
        mcontext = context;
        marrayListEmployee = arrayListEmployee;
    }

  /*  public MyAdapter(@NonNull Context context, List<Employee> arrayListEmployee) {
        super(context, R.layout.custom_list_item,arrayListEmployee);

        this.context = context;
        this.arrayListEmployee = arrayListEmployee;

    }
*/
  @Override
  public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
      View v = LayoutInflater.from(mcontext).inflate(R.layout.custom_list_item, parent, false);
      MyViewHolder evh = new MyViewHolder(v);
      return evh;

  }
    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {
        Employee currentItem = marrayListEmployee.get(position);
        String tvID = currentItem.getId();
        String tvName = currentItem.getnumber();
        holder.tvID.setText(tvID);
        holder.tvName.setText(tvName);


    }
    @Override
    public int getItemCount() {
        return marrayListEmployee.size();
    }
    public class MyViewHolder extends RecyclerView.ViewHolder {

        public TextView tvID;
        public TextView tvName;
        public MyViewHolder(View itemView) {
            super(itemView);

            tvID = itemView.findViewById(R.id.txt_id);
            tvName = itemView.findViewById(R.id.number);
            itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (mListener != null) {
                        int position = getAdapterPosition();
                        if (position != RecyclerView.NO_POSITION) {
                            mListener.onItemClick(position);

                        }
                    }
                }
            });
        }
    }
 
   public void filterList(ArrayList<Employee> filteredList) {
       marrayListEmployee = filteredList;
       notifyDataSetChanged();
   }
}

回答1:


You have to get element from the list that was changed after filter not the old list

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);
   }
  ...
}



回答2:


EDITED

Sorry I didn't see the correct answer marked...

I will not delete, use this to improve some things

Don't copy/paste code because it's not tested, try to understand the changes

In filter method you replaced marrayListEmployee with filteredList and in retrieveData method you didn set anything, just notified adapter

Adapter

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder>{

    private Context mcontext;
    private ArrayList<Employee> marrayListEmployee;
    private OnItemClickListener mListener;

    public interface OnItemClickListener {
        void onItemClick(int position);
    }
    public void setOnItemClickListener(OnItemClickListener listener) {
        mListener = listener;
    }
    public MyAdapter(Context context, ArrayList<Employee> arrayListEmployee) {
        mcontext = context;
        marrayListEmployee = arrayListEmployee;
    }

    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(mcontext).inflate(R.layout.custom_list_item, parent, false);
        return new MyViewHolder(v);

    }
    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {
        Employee currentItem = marrayListEmployee.get(position);
        holder.tvID.setText(currentItem.getId());
        holder.tvName.setText(currentItem.getnumber());

        //TODO set setOnClickListener here instead in ViewHolder constructor
        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mListener != null) {
                    int position = holder.getAdapterPosition();
                    if (position != RecyclerView.NO_POSITION) {
                        mListener.onItemClick(position);

                    }
                }
            }
        });
    }


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


    public void filterList(ArrayList<Employee> filteredList) {
        marrayListEmployee = filteredList;
        notifyDataSetChanged();
    }




    public class MyViewHolder extends RecyclerView.ViewHolder {

        public TextView tvID;
        public TextView tvName;

        public MyViewHolder(View itemView) {
            super(itemView);
            tvID = itemView.findViewById(R.id.txt_id);
            tvName = itemView.findViewById(R.id.number);
        }
    }
}

Activity - onCreate

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
         
        ......

        removeView = findViewById(R.id.exit_entry);
        removeView.setHasFixedSize(true);
        removeView.setLayoutManager(new LinearLayoutManager(this));
        mEmployeeList = new ArrayList<>(); 
        removeView.setAdapter(new MyAdapter(this, mEmployeeList));
        myadapter.setOnItemClickListener(this); //TODO set click listener here instead evrytime in retrieveData method
         
        .........
 
    }

RetrieveData data method

public void retrieveData() {
        StringRequest request = new StringRequest(Request.Method.POST, Show_url,
                new Response.Listener<String>() {
                    @Override
                    public void onResponse(String response) {
                        mEmployeeList.clear();
                        try {

                            JSONObject jsonObject = new JSONObject(response);
                            String sucess = jsonObject.getString("success");

                            JSONArray jsonArray = jsonObject.getJSONArray("user_data");

                            if (sucess != null && sucess.equals("1")) { //check null

                                for (int i = 0; i < jsonArray.length(); i++) {

                                    JSONObject object = jsonArray.getJSONObject(i);
                                    String id = object.getString("id");
                                    String vehicle_number = object.getString("number");
                                    String driver_name = object.getString("name");
                                    String entry_time = object.getString("time");
                                    String entry_date = object.getString("date");
                                    String exit_time = object.getString("ttime");
                                    String yes = object.getString("yes");
                                    mEmployeeList.add(new Employee(id, number, name, time, date, ttime, yes));
                                }
                                //myadapter.notifyDataSetChanged(); // remove this,
                                //myadapter.setOnItemClickListener(exit_Activity.this); remove this, set it in onCreate method
                                //TODO you have to reset mEmployeeList (below) because you changed it by filtering
                                myadapter.filterList(mEmployeeList); // change method name to swapData()
                                progressBar.setVisibility(View.GONE);
                                mSwipeRefreshLayout.setRefreshing(false);
                                Toast.makeText(getApplicationContext(), "List Updated", Toast.LENGTH_SHORT).show();
                            }


                        } catch (JSONException e) {
                            e.printStackTrace();
                        }


                    }

                }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                Toast.makeText(exit_Activity.this, error.getMessage(), Toast.LENGTH_LONG).show();
                error.printStackTrace();
            }
        });
        RequestQueue requestQueue = Volley.newRequestQueue(this);
        requestQueue.add(request);

    }

filter method

private void filter(String text) {
        if(text == null || text.isEmpty()) return;
        ArrayList<Employee> filteredList = new ArrayList<>();
        for (Employee item : mEmployeeList) {
            if (item.getVehicle_number() == null) continue; // TODO check null
            if (item.getVehicle_number().toLowerCase().contains(text.toLowerCase())) {
                filteredList.add(item);
            }
        }
        myadapter.filterList(filteredList); // change method name to swapData()
    }


来源:https://stackoverflow.com/questions/65876114/after-filter-a-recyclerview-item-and-clicking-it-gives-wrong-item

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