简体   繁体   中英

Show wrong data when filtered RecyclerView item is clicked

I have a RecyclerView with edittext for search 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. i am new in programming, please help :).

Here is the code of my Adapter.

public class ProjectAdapter extends RecyclerView.Adapter<ProjectAdapter.ProjectViewHolder> {

    private Context mCtx;
    private List<Project> projectList;
    private OnItemClickListener mListener;


    public interface OnItemClickListener {
        void onItemClick(int position);

    }



    public void setOnItemClickListener(OnItemClickListener listener) {
        mListener = listener;
    }





    public ProjectAdapter(Context mCtx, List<Project> projectList) {
        this.mCtx = mCtx;
        this.projectList = projectList;
    }

    @Override
    public ProjectViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        LayoutInflater inflater = LayoutInflater.from(mCtx);
        View view = inflater.inflate(R.layout.project_list, null);
        return new ProjectAdapter.ProjectViewHolder(view);
    }


    @Override
    public void onBindViewHolder(ProjectViewHolder holder, int position) {
        Project project = projectList.get(position);
        holder.textViewProject.setText(project.getProject());

    }


    @Override
    public int getItemCount() {

        return projectList.size();
    }



    class ProjectViewHolder extends RecyclerView.ViewHolder {

        TextView textViewProject;


        public ProjectViewHolder(View itemView) {
            super(itemView);

            textViewProject = itemView.findViewById(R.id.textViewProject);

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

                        }
                    }
                }
            });


        }
    }
}

and this is my ListprojectActivity.java

public class ListprojectActivity extends AppCompatActivity implements ProjectAdapter.OnItemClickListener {

    public static final String project_select = "project";

    private static final String URL_PRODUCTS = "http://192.168.43.245/android_register_login/Api_1.php";
    EditText editTextProject;

    //a list to store all the products
    List<Project> projectList;




    //the recyclerview
    RecyclerView recyclerView;

    ProjectAdapter adapter;

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

        //getting the recyclerview from xml
        recyclerView = findViewById(R.id.recylcerViewProject);
        recyclerView.setHasFixedSize(true);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        editTextProject = findViewById(R.id.EditTextProject);
        LinearLayoutManager layoutManager = new LinearLayoutManager(this);

        DividerItemDecoration itemDecoration = new DividerItemDecoration(this, layoutManager.getOrientation());
        recyclerView.setHasFixedSize(true);
        recyclerView.setLayoutManager(layoutManager);
        recyclerView.addItemDecoration(itemDecoration);



        //initializing the productlist
        projectList = new ArrayList<>();


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

                final String query = s.toString().toLowerCase().trim();
                final ArrayList<Project> filteredList = new ArrayList<>();


                for (int i = 0; i < projectList.size(); i++) {

                    final String text = projectList.get(i).getProject().toLowerCase();
                    if (text.contains(query)) {
                        filteredList.add(projectList.get(i));
                    }
                }

                recyclerView.setLayoutManager(new LinearLayoutManager(ListprojectActivity.this));
                adapter = new ProjectAdapter(ListprojectActivity.this, filteredList);
                recyclerView.setAdapter(adapter);
                adapter.setOnItemClickListener(ListprojectActivity.this);
                adapter.notifyDataSetChanged();




            }

            @Override
            public void afterTextChanged(Editable s) {


            }
        });


        //this method will fetch and parse json
        //to display it in recyclerview
        loadProjects();
    }

    private void loadProjects() {

        /*
         * Creating a String Request
         * The request type is GET defined by first parameter
         * The URL is defined in the second parameter
         * Then we have a Response Listener and a Error Listener
         * In response listener we will get the JSON response as a String
         * */
        StringRequest stringRequest = new StringRequest(Request.Method.GET, URL_PRODUCTS,
                new Response.Listener<String>() {
                    @Override
                    public void onResponse(String response) {
                        try {
                            //converting the string to json array object
                            JSONArray array = new JSONArray(response);

                            //traversing through all the object
                            for (int i = 0; i < array.length(); i++) {

                                //getting product object from json array
                                JSONObject project = array.getJSONObject(i);

                                //adding the product to product list

                                projectList.add(new Project(
                                        project.getInt("id_project"),
                                        project.getString("project")
                                ));
                            }

                            //creating adapter object and setting it to recyclerview
                            ProjectAdapter adapter = new ProjectAdapter(ListprojectActivity.this, projectList);
                            recyclerView.setAdapter(adapter);
                            adapter.setOnItemClickListener(ListprojectActivity.this);

                        } catch (JSONException e) {
                            e.printStackTrace();
                        }
                    }
                },
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {

                    }
                });

        //adding our stringrequest to queue
        Volley.newRequestQueue(this).add(stringRequest);
    }


    @Override
    public void onItemClick(int position) {
        Intent detailMasalah = new Intent(this, ListproblemActivity.class);
        Project projectclick = projectList.get(position);

        detailMasalah.putExtra(project_select, projectclick.getProject());

        startActivity(detailMasalah);
    }
}

and project.java

public class Project {

    private int id_project;
    private String project;

    public Project (int id_project, String project) {
        this.id_project = id_project;
        this.project = project;
    }


    public int getId() {
        return id_project;
    }

    public String getProject() {
        return project;
    }


}

Try this

@Override
    public void onBindViewHolder(ProjectViewHolder holder, int position) {
        Project project = projectList.get(position);
        holder.textViewProject.setText(project.getProject());


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

                    }
                }
            }
        });

    }

It happened because you are setting the listener in your ViewHolder class instead of your onBindViewHolder . As the viewholder is recycled, no new objects are created after some scrolling. The created object's click listener is bound to the item that first created it.

As Vishrut mentioned, you should move the listener to onBindViewHolder .

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