简体   繁体   English

RecyclerView 中的定位是如何工作的?

[英]How does positioning work in RecyclerView?

So I have a little problem where I have a giant recycler view (7000 items) and I have it filled up with generated cards that have college information on them and a button on the right hand side.所以我有一个小问题,我有一个巨大的回收站视图(7000 件物品),我在里面填满了生成的卡片,卡片上有大学信息,右侧有一个按钮。 I included a picture for you to see exactly what I mean.我附上了一张图片让你明白我的意思。 So here is the question: I want to fetch the name and ID when I click on the "details" button so that I can query the rest of college information from an SQLite database later but when I scroll down enough and click the button it sometimes returns information of other college instead of the one I want.所以问题是:我想在单击“详细信息”按钮时获取姓名和 ID,以便稍后可以从 SQLite 数据库查询其余的大学信息,但是当我向下滚动并单击按钮时,有时返回其他大学的信息,而不是我想要的。 The first one always works as intended though.不过,第一个总是按预期工作。 Here is the adapter code:这是适配器代码:

public class CustomRecyclerAdapter extends RecyclerView.Adapter<CustomRecyclerAdapter.CustomViewHolder> implements Filterable {

    private List<CollegeItem> collegeList;
    private List<CollegeItem> collegeListFull;
    private ItemClickListener itemClickListener;
    private Context context;
    private Button details;
    private DatabaseCollege collegeDB;

    public CustomRecyclerAdapter(List<CollegeItem> collegeList, Context context) {
        this.collegeList = collegeList;
        this.context = context;
        collegeListFull = new ArrayList<>(collegeList);
    }

    @NonNull
    @Override
    public CustomRecyclerAdapter.CustomViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(context).inflate(R.layout.college_item, parent, false);
        return new CustomRecyclerAdapter.CustomViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(CustomRecyclerAdapter.CustomViewHolder holder, int position) {
        final String id = collegeList.get(position).getId();
        final String name = collegeList.get(position).getName();
        holder.name.setText(collegeList.get(position).getName());
        holder.id.setText(collegeList.get(position).getId());
        details.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                System.out.println(id + " - " + name); //This sometimes gives information of incorrect college when clicked
            }
        });
    }

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

    public void setItemClickListener(ItemClickListener itemClickListener) {
        this.itemClickListener = itemClickListener;
    }

    @Override
    public Filter getFilter() {
        return collegeFilter;
    }

    public Filter getFilterName() {
        return collegeFilterName;
    }

    private Filter collegeFilter = new Filter() {
        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            List<CollegeItem> filteredList = new ArrayList<>();

            if(constraint == null || constraint.length() == 0) {
                filteredList.addAll(collegeListFull);
            } else {
                String filterPattern = constraint.toString().toLowerCase().trim();

                for(CollegeItem college : collegeListFull) {
                    if(college.getName().toLowerCase().contains(filterPattern)) {
                        filteredList.add(college);
                    }
                }
            }
            FilterResults results = new FilterResults();
            results.values = filteredList;
            return results;
        }

        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {
            collegeList.clear();
            collegeList.addAll((List) results.values);
            notifyDataSetChanged();
        }
    };

    private Filter collegeFilterName = new Filter() {
        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            List<CollegeItem> filteredList = new ArrayList<>();

            if(constraint == null || constraint.length() == 0) {
                filteredList.addAll(collegeListFull);
            } else {
                String filterPattern = constraint.toString().toLowerCase().trim();

                for(CollegeItem college : collegeListFull) {
                    if(college.getId().toLowerCase().contains(filterPattern)) {
                        filteredList.add(college);
                    }
                }
            }
            FilterResults results = new FilterResults();
            results.values = filteredList;
            return results;
        }

        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {
            collegeList.clear();
            collegeList.addAll((List) results.values);
            notifyDataSetChanged();
        }
    };

    public class CustomViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
        TextView name, id;

        public CustomViewHolder(View v) {
            super(v);
            name = v.findViewById(R.id.college_name);
            id = v.findViewById(R.id.college_id);
            details = v.findViewById(R.id.btn_college_details);
        }

        @Override
        public void onClick(View v) {
            if(itemClickListener != null) {
                itemClickListener.onClick(v, getAdapterPosition());
            }
        }
    }
}

I am not sure exactly why but it seems to be a positioning issue maybe?我不确定到底是为什么,但这似乎是一个定位问题? Because when I scroll and click the information outputed seem to change.因为当我滚动并单击时,输出的信息似乎发生了变化。 Whats the correct way to get the information from the cards the way I want?以我想要的方式从卡片中获取信息的正确方法是什么? 在此处输入图片说明

and just in case here is the fragment java code where the recycler view sits:以防万一这里是回收器视图所在的片段 java 代码:

public class CollegeFragment extends Fragment implements ItemClickListener{

    private RecyclerView recyclerView;
    private CustomRecyclerAdapter customRecyclerAdapter;
    private List<CollegeItem> collegeItemList = new ArrayList<>();
    private DatabaseCollege dbCollege;
    private EditText cName, cId;


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        final View myFragmentView = inflater.inflate(R.layout.fragment_college, container, false);

        dbCollege = new DatabaseCollege(getActivity());

        recyclerView = myFragmentView.findViewById(R.id.recycler);
        customRecyclerAdapter = new CustomRecyclerAdapter(dbCollege.getCollegeData(), getActivity());

        RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false);
        recyclerView.setLayoutManager(layoutManager);
        recyclerView.setItemAnimator(new DefaultItemAnimator());
        recyclerView.setAdapter(customRecyclerAdapter);
        customRecyclerAdapter.setItemClickListener(this);

        cId = myFragmentView.findViewById(R.id.et_ipeds);
        cId.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) {
                cName.getText().clear();
                CollegeFragment.this.customRecyclerAdapter.getFilter().filter(s);
            }

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

        cName = myFragmentView.findViewById(R.id.et_name);
        cName.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) {
                cId.getText().clear();
                CollegeFragment.this.customRecyclerAdapter.getFilterName().filter(s);
            }

            @Override
            public void afterTextChanged(Editable s) {

            }
        });
        return myFragmentView;

    }

    @Override
    public void onClick(View v, int position) {
        String name = collegeItemList.get(position).getName();
        String id = collegeItemList.get(position).getId();
    }
}

Adapter适配器

public class CustomRecyclerAdapter extends RecyclerView.Adapter<CustomRecyclerAdapter.CustomViewHolder> implements Filterable {

    private List<CollegeItem> collegeList;
    private List<CollegeItem> collegeListFull;
    private ItemClickListener itemClickListener;
    private Context context;
    private DatabaseCollege collegeDB;

    public CustomRecyclerAdapter(List<CollegeItem> collegeList, Context context) {
        this.collegeList = collegeList;
        this.context = context;
        collegeListFull = new ArrayList<>(collegeList);
    }

    @NonNull
    @Override
    public CustomRecyclerAdapter.CustomViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(context).inflate(R.layout.college_item, parent, false);
        return new CustomRecyclerAdapter.CustomViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(CustomRecyclerAdapter.CustomViewHolder holder, int position) {
        final String id = collegeList.get(position).getId();
        final String name = collegeList.get(position).getName();
        holder.name.setText(collegeList.get(position).getName());
        holder.id.setText(collegeList.get(position).getId());
    }

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

    public void setItemClickListener(ItemClickListener itemClickListener) {
        this.itemClickListener = itemClickListener;
    }

    @Override
    public Filter getFilter() {
        return collegeFilter;
    }

    public Filter getFilterName() {
        return collegeFilterName;
    }

    private Filter collegeFilter = new Filter() {
        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            List<CollegeItem> filteredList = new ArrayList<>();

            if(constraint == null || constraint.length() == 0) {
                filteredList.addAll(collegeListFull);
            } else {
                String filterPattern = constraint.toString().toLowerCase().trim();

                for(CollegeItem college : collegeListFull) {
                    if(college.getName().toLowerCase().contains(filterPattern)) {
                        filteredList.add(college);
                    }
                }
            }
            FilterResults results = new FilterResults();
            results.values = filteredList;
            return results;
        }

        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {
            collegeList.clear();
            collegeList.addAll((List) results.values);
            notifyDataSetChanged();
        }
    };

    private Filter collegeFilterName = new Filter() {
        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            List<CollegeItem> filteredList = new ArrayList<>();

            if(constraint == null || constraint.length() == 0) {
                filteredList.addAll(collegeListFull);
            } else {
                String filterPattern = constraint.toString().toLowerCase().trim();

                for(CollegeItem college : collegeListFull) {
                    if(college.getId().toLowerCase().contains(filterPattern)) {
                        filteredList.add(college);
                    }
                }
            }
            FilterResults results = new FilterResults();
            results.values = filteredList;
            return results;
        }

        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {
            collegeList.clear();
            collegeList.addAll((List) results.values);
            notifyDataSetChanged();
        }
    };

    public class CustomViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
        TextView name, id;
        Button details; // Button should be here

        public CustomViewHolder(View v) {
            super(v);
            name = v.findViewById(R.id.college_name);
            id = v.findViewById(R.id.college_id);
            details = v.findViewById(R.id.btn_college_details);

            details.setOnClickListener(this); // set click listener here instead
        }

        @Override
        public void onClick(View v) {
            if(itemClickListener != null) {
                itemClickListener.onClick(v, getAdapterPosition());
            }
        }
    }
}

Here, you're utilizing the ItemClickListener callback that you implemented in your fragment instead of creating new instances of click listener for your details button.在这里,您使用的是在片段中实现的 ItemClickListener 回调,而不是为详细信息按钮创建新的点击侦听器实例。 In this case, your listener for all items is your Fragment that implements ItemClickListener在这种情况下,所有项目的侦听器是实现ItemClickListener Fragment

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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