Background color or Images shuffling on scrolling in recyclerview?

后端 未结 3 583
鱼传尺愫
鱼传尺愫 2020-12-11 07:39

I am wondering that my images and color of layouts shuffling when i scrolls downwards or upwards, I created cardview using recyclerview. and set an image(changes color on cl

相关标签:
3条回答
  • 2020-12-11 08:02

    I have created a working example of what you are trying to accomplish. The source of the errors you experience is mostly that you don't understand view recycling. I am not going to explain the whole thing to you now, but anyway here is the example:


    For the example I used this layout for each row:

    <?xml version="1.0" encoding="utf-8"?>
    <FrameLayout
        android:id="@+id/background"
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="80dp">
    
        <TextView
            android:id="@+id/textView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center"/>
    
    </FrameLayout>
    

    I used this model:

    public class ExampleModel {
    
        private final int mColor;
        private final String mText;
    
        public ExampleModel(int color, String text) {
            mColor = color;
            mText = text;
        }
    
        public int getColor() {
            return mColor;
        }
    
        public String getText() {
            return mText;
        }
    }
    

    And this view holder:

    public class ExampleViewHolder extends RecyclerView.ViewHolder {
    
        private final FrameLayout mBackground;
        private final TextView mTextView;
    
        public ExampleViewHolder(View itemView) {
            super(itemView);
    
            mBackground = (FrameLayout) itemView.findViewById(R.id.background);
            mTextView = (TextView) itemView.findViewById(R.id.textView);
        }
    
        public void bind(ExampleModel model) {
            mBackground.setBackgroundColor(model.getColor());
            mTextView.setText(model.getText());
        }
    }
    

    As you can see nothing special, the Adapter implementation is equally simple:

    public class ExampleAdapter extends RecyclerView.Adapter<ExampleViewHolder> {
    
        private final LayoutInflater mInflater;
        private final List<ExampleModel> mModels;
    
        public ExampleAdapter(Context context, List<ExampleModel> models) {
            mInflater = LayoutInflater.from(context);
            mModels = models;
        }
    
        @Override
        public ExampleViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            final View itemView = mInflater.inflate(R.layout.item_example, parent, false);
            return new ExampleViewHolder(itemView);
        }
    
        @Override
        public void onBindViewHolder(ExampleViewHolder holder, int position) {
            final ExampleModel model = mModels.get(position);
            holder.bind(model);
        }
    
        @Override
        public int getItemCount() {
            return mModels.size();
        }
    }
    

    And you use the whole thing like this:

    final Random mRandom = new Random(System.currentTimeMillis());
    
    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
    
        recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
    
        final List<ExampleModel> models = new ArrayList<>();
        for (int i = 0; i < 100; i++) {
            final int randomColor = generateRandomPastelColor();
            models.add(new ExampleModel(randomColor, String.valueOf(i)));
        }
    
        final ExampleAdapter adapter = new ExampleAdapter(getActivity(), models);
        recyclerView.setAdapter(adapter);
    }
    
    public int generateRandomPastelColor() {
        final int baseColor = Color.WHITE;
    
        final int red = (Color.red(baseColor) + mRandom.nextInt(256)) / 2;
        final int green = (Color.green(baseColor) + mRandom.nextInt(256)) / 2;
        final int blue = (Color.blue(baseColor) + mRandom.nextInt(256)) / 2;
    
        return Color.rgb(red, green, blue);
    }
    

    This should do what you are looking for and you can use it as an example of how to implement your Adapter.

    0 讨论(0)
  • 2020-12-11 08:20

    I got the same problem ,when i used the radioButton in my listView row, I solved it. As in every scrolling the Cache is cleared, you have to store the changed data in every row. just check my code

    @Override
        public View getView(final int position, View convertView, ViewGroup parent) {
            // TODO Auto-generated method stub
    //      if(position==0)
    //      Toast.makeText(context, ""+QuestionViewPageAdapter.mRadioGroupData, Toast.LENGTH_SHORT).show();
    
            final ViewHolder viewHolder;
            View row=convertView;
    
            radioButton=new RadioButton[Integer.parseInt(mNoOfCategoryGreading)];
    
    
    
                LayoutInflater inflater =LayoutInflater.from(context);//(LayoutInflater)context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
                row = inflater.inflate(R.layout.question_row, parent, false);
    
                viewHolder=new ViewHolder();
    
                viewHolder.tv_qContent=(TextView)row.findViewById(R.id.tv_question);
                viewHolder.rg=(RadioGroup)row.findViewById(R.id.rgrp);
    
                for(int i=0;i<Integer.parseInt(mNoOfCategoryGreading);i++)
                {
                    radioButton[i]=new RadioButton(context);
                    radioButton[i].setLayoutParams(new RadioGroup.LayoutParams(0, LayoutParams.WRAP_CONTENT,1f));
                    //1f for layout_weight="1"
                    radioButton[i].setId(i);
                    radioButton[i].setText(""+(i+1));
    
                    viewHolder.rg.addView(radioButton[i]);
                }
                row.setTag(viewHolder);
    
    
                for(int i=0;i<QuestionViewPageAdapter.mRadioGroupData.size();i++){
                    int p=Integer.parseInt(""+QuestionViewPageAdapter.mRadioGroupData.get(i).get("position"));
                    String id=QuestionViewPageAdapter.mRadioGroupData.get(i).get("Id");
                    if(p!=-1 && id.equals(""+data.get(position).get(AppData.question_Set_category_QuestionID)))
                    {//radioButton[p].setSelected(true);
                        viewHolder.rg.check(p-1);}
                    //Toast.makeText(context, "Yes "+p, Toast.LENGTH_LONG).show();}
                }
    
            viewHolder.tv_qContent.setText((position+1)+". "+data.get(position).get(AppData.question_Set_category_QuestionContent));
            viewHolder.tv_qContent.setTypeface(typeface_muso_regular300);
    
    
    
            viewHolder.rg.setOnCheckedChangeListener(new OnCheckedChangeListener() {
    
                @Override
                public void onCheckedChanged(RadioGroup group, int checkedId) {
                    // TODO Auto-generated method stub
    
                    String s=data.get(position).get(AppData.question_Set_category_QuestionID);
                    isAvailabel(s);
    
    
                            int radioButtonID = viewHolder.rg.getCheckedRadioButtonId();
                            View radioButton = viewHolder.rg.findViewById(radioButtonID);
                            int idx = viewHolder.rg.indexOfChild(radioButton);
                            HashMap<String, String> map=new HashMap<String, String>();
                            map.put("position", ""+(idx+1));
                            map.put("Id", ""+data.get(position).get(AppData.question_Set_category_QuestionID));
                            map.put("CategoryId", ""+mCategoryId);
                            QuestionViewPageAdapter.mRadioGroupData.add(map);
                    }
    
    
            });
    
    
    
    
    
            return row;
        }
    
        private void isAvailabel(String qId){
    
            for(int i=0;i<QuestionViewPageAdapter.mRadioGroupData.size();i++){
                if(qId.equals(QuestionViewPageAdapter.mRadioGroupData.get(i).get("Id"))){
                    position=i;
    
                    QuestionViewPageAdapter.mRadioGroupData.remove(i);
                }
            }
    
        }
    
         class ViewHolder {
             TextView tv_qContent ,tv_1,tv_2,tv_3;
                RadioGroup rg;
                RadioButton rBtn1,rBtn2,rBtn3,rBtn4,rBtn5;
         }
    
    0 讨论(0)
  • 2020-12-11 08:22

    In my case overriding getItemId and setting sethasStableIds to true solved the shuffling issue.

    in adapter:

        @Override
        public long getItemId(int position) {
        Object listItem = feeds.get(position);
        return listItem.hashCode();
        }
    

    in main activity/fragment :

        adapter = new FeedAdapter(feeds, getContext());
        adapter.setHasStableIds(true);
    
    0 讨论(0)
提交回复
热议问题