RecyclerView Adapter Lint Error do not treat position as fixed

拥有回忆 提交于 2019-12-10 11:51:27

问题


I have surf this type of error but I didn't get what can I do in my case.

I am getting following lint error.

Do not treat position as fixed; only use immediately and call holder.getAdapterPosition() to look it up later.

RecyclerView will not call onBindViewHolder again when the position of the item changes in the data set unless the item itself is invalidated or the new position cannot be determined. For this reason, you should only use the position parameter while acquiring the related data item inside this method, and should not keep a copy of it.

If you need the position of an item later on (e.g. in a click listener), use getAdapterPosition() which will have the updated adapter position.

My RecyclerView Adapter:

   /**
     * Right Content Adapter
     */
    public class RightContentAdapter
            extends RecyclerView.Adapter<RightContentAdapter.ViewHolder> {

        public final ArrayList<IdNamePair> mValues;
        public Activity context;
        private int pos;

        public RightContentAdapter(Activity context, ArrayList<IdNamePair> items) {
            mValues = items;
            this.context = context;

        }

        @Override
        public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View view = LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.activity_filter_checkbox, parent, false);

            Log.logInfo("onCreateViewHolder call");

            return new ViewHolder(view);
        }

        @Override
        public void onBindViewHolder(final ViewHolder holder, final int position) {
            final IdNamePair idNamePair = mValues.get(position);
            holder.onBind = true;
            Log.logError("onBind");
            if (idNamePair.getName() != null) {
                holder.mItemCheckBox.setText(idNamePair.getName());
                holder.mItemCheckBox.setChecked(idNamePair.isChecked());

                if (idNamePair.isChecked())
                    countFilter++;
            }

            holder.onBind = false;
            holder.mItemCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
                @Override
                public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                    Log.logInfo("isChecked : " + isChecked);
                    boolean check = false;
                    if (isChecked)
                        countFilter++;
                    else {
                        countFilter--;
                    }
                    if (filterAttributeArrayList != null) {
                        int filterAttribSize = filterAttributeArrayList.size();
                        for (int i = 0; i < filterAttribSize; i++) {
                            FilterAttribute fa = filterAttributeArrayList.get(i);
                            if (selectedAttributeName.equalsIgnoreCase(fa.getAttrName())) {
                                check = true;

                                filterAttributeArrayList.get(i).getAttrVal().get(position).setIsChecked(isChecked);
                                filterAttributeArrayList.get(i).setFilterCount(countFilter);
                                mValues.get(position).setIsChecked(isChecked);
                                //countFilter = 0;
                                // if(!holder.onBind)
                                // notifyItemChanged(position);


                                //mRightContentAdapter.notifyItemChanged(position);
                                break;
                            }
                        }
                    }
                    if (!check) {
                        if (staticFilterArrayList != null) {
                            int staticFilterSize = staticFilterArrayList.size();
                            for (int i = 0; i < staticFilterSize; i++) {
                                StaticFilterData sf = staticFilterArrayList.get(i);
                                if (selectedAttributeName.equalsIgnoreCase(sf.getDisplayName())) {

                                    staticFilterArrayList.get(i).getValue().get(position).setIsChecked(isChecked);
                                    staticFilterArrayList.get(i).setFilterCount(countFilter);
                                    mValues.get(position).setIsChecked(isChecked);
                                    //  countFilter = 0;
                                    //     if(!holder.onBind)
                                    //       notifyItemChanged(position);
                                    //mRightContentAdapter.notifyItemChanged(position);
                                    break;
                                }
                            }
                        }
                    }

                }
            });
        }

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

        //View Holder
        public class ViewHolder extends RecyclerView.ViewHolder {

            //  private final View mView;
            private CheckBox mItemCheckBox;

            ViewHolder(View view) {
                super(view);
                //     mView = view;
                mItemCheckBox = (CheckBox) view.findViewById(R.id.filter_checkbox);
                mItemCheckBox.setTypeface(Font.getMyRiadProRegular(context));
            }
        }
    }

I have used it to make Filter type Activity like Flipkart. Sometimes checkbox also getting unchecked automatically while scrolling. Is there anything wrong in my code?

Thank you.


回答1:


Do not make position as final in onBindViewHolder method instead of that make only holder as final and make use of holder.getAdapterPosition() wherever you are using position.

Don't even do something like this: int var = holder.getAdapterPosition(), straight away use holder.getAdapterPosition(). Your first problem is solved. :)

Next when you are scrolling then some of your checkboxes gets unchecked because recyclerView reuses the itemView instead of creating new that's why it is better than listView. So you need to handle it properly. If you can tell exactly what you are trying to do in onCheckChangedListener then I can surely help you out in handling this.



来源:https://stackoverflow.com/questions/37498233/recyclerview-adapter-lint-error-do-not-treat-position-as-fixed

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