在每第八个位置的RecyclerView中,点击时查看颜色变化。

huangapple go评论60阅读模式
英文:

View color changing on click changes at every 8th position RecyclerView

问题

当我点击RecyclerView的第0个位置以改变视图的颜色时,它也会在第8个、第16个和第24个位置改变颜色(我在RecyclerView中总共有26个项目),如果我点击位置1,它会在第1个、第9个、第17个和第25个位置改变颜色,依此类推。我该如何修复这个问题?

我的RecyclerView适配器是:

public class AdapterOccupiedRoomCleaning extends RecyclerView.Adapter<AdapterOccupiedRoomCleaning.ViewHolder> {
    // 适配器的代码...
}

我的Java类是:

public class OccupiedRoomCleaning extends AppCompatActivity {
    // 类的代码...
}

我在这里做错了什么,导致它在每8个项目处改变颜色?

英文:

So when i click on the 0 position of recyclerview to change the color of the view it also changes the color at 8th, 16th and 24th position (i have a total of 26 items in recyclerview), if i click on position 1 it changes color at 1st, 9th, 17th and 25th and so on. how do i fix this

My recyclerview adapter is

public class AdapterOccupiedRoomCleaning extends RecyclerView.Adapter&lt;AdapterOccupiedRoomCleaning.ViewHolder&gt; {
    private List&lt;ItemsAdapter&gt; mList;
    private Context mContext;

    public AdapterOccupiedRoomCleaning(List&lt;ItemsAdapter&gt; list, Context context){
        super();
        mList = list;
        mContext = context;
    }
    @NonNull
    @Override
    public AdapterOccupiedRoomCleaning.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int i) {
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.occupiedrooms_cleaning_item, parent, false);
        ViewHolder viewHolder = new ViewHolder(v);

        return viewHolder;
    }
    @Override
    public void onBindViewHolder(@NonNull AdapterOccupiedRoomCleaning.ViewHolder viewHolder, int position) {
        ItemsAdapter itemAdapter = mList.get(position);
        ((ViewHolder) viewHolder).setUrduText.setText(itemAdapter.getUrdutext());
        ((ViewHolder) viewHolder).setEnglishText.setText(itemAdapter.getEnglishText());
        ((ViewHolder) viewHolder).setCleaningImage.setImageResource(itemAdapter.getImage());
//        ((ViewHolder) viewHolder).background.setOnClickListener(new View.OnClickListener() {
//            @Override
//            public void onClick(View v) {
//
//                //viewHolder.background.setBackgroundColor(Color.parseColor(&quot;#08A467&quot;));
//                
//                Toast.makeText(mContext, &quot;Recycle Click &quot; + viewHolder.setEnglishText.getText().toString(), Toast.LENGTH_SHORT).show();
//            }
//        });

        viewHolder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                viewHolder.background.setBackgroundColor(Color.parseColor(&quot;#08A467&quot;));
            }
        });
    }

    @Override
    public int getItemCount() {
        //notifyDataSetChanged();
        return mList.size();
    }


    class ViewHolder extends RecyclerView.ViewHolder{
        public TextView setUrduText, setEnglishText;
        public ImageView setCleaningImage;
        public View background;
        public ViewHolder(View itemView) {
            super(itemView);
            setUrduText = (TextView) itemView.findViewById(R.id.urduTextView);
            setEnglishText = (TextView) itemView.findViewById(R.id.englishTextView);
            setCleaningImage = (ImageView) itemView.findViewById(R.id.imageCleaning);
            background = (View) itemView.findViewById(R.id.backgroundColor);
        }
    }
}

My java class is

public class OccupiedRoomCleaning extends AppCompatActivity {

    String getQrCode, patientMRNO, roomNumber;
    private RecyclerView mRecycleview;
    private List&lt;ItemsAdapter&gt; mList = new ArrayList&lt;&gt;();
    private AdapterOccupiedRoomCleaning mAdapter;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_occupied_room_cleaning);


        getQrCode = getIntent().getExtras().getString(&quot;qrcode&quot;);

        init();
        addList();
        adapter();
    }
    private void init(){
        mRecycleview = findViewById(R.id.recyclerview);
    }
    private void addList(){

        ItemsAdapter itemAdapter = new ItemsAdapter();
        itemAdapter.setImage(R.drawable.pillowclean);
        itemAdapter.setUrdutext(&quot;sdf&quot;);
        itemAdapter.setEnglishText(&quot;Pillow Parachute Cover Cleaning&quot;);
        mList.add(itemAdapter);

        itemAdapter = new ItemsAdapter();
        itemAdapter.setImage(R.drawable.bedclean);
        itemAdapter.setUrdutext(&quot;sdfs&quot;);
        itemAdapter.setEnglishText(&quot;Patient Bed Cleaning(Blood Spots)&quot;);
        mList.add(itemAdapter);

       //... more items




    }
    private void adapter(){
        Log.d(&quot;anhtt&quot;,&quot;mlist : &quot; +mList.size());
        mAdapter = new AdapterOccupiedRoomCleaning(mList, this);
       
        mRecycleview.setAdapter(mAdapter);
        mRecycleview.setLayoutManager(new LinearLayoutManager(this));

    }

}

what am i doing wrong here that it changes color at every 8th item

答案1

得分: 2

由于RecyclerView重用视图而不创建新视图,您需要在onBindViewHolder函数中设置默认颜色。

@Override
public void onBindViewHolder(@NonNull AdapterOccupiedRoomCleaning.ViewHolder viewHolder, int position) {
    ItemsAdapter itemAdapter = mList.get(position);
    ((ViewHolder) viewHolder).setUrduText.setText(itemAdapter.getUrdutext());
    ((ViewHolder) viewHolder).setEnglishText.setText(itemAdapter.getEnglishText());
    ((ViewHolder) viewHolder).setCleaningImage.setImageResource(itemAdapter.getImage());

    // 添加这行代码
    ((ViewHolder) viewHolder).background.setBackgroundColor(Color.parseColor("默认颜色"));

    viewHolder.itemView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
             viewHolder.background.setBackgroundColor(Color.parseColor("#08A467"));
        }
    });
}
英文:

Since, a Recycler view reuses the views and do not create new views, you need to set default color in onBindViewHolder function.

@Override
public void onBindViewHolder(@NonNull AdapterOccupiedRoomCleaning.ViewHolder viewHolder, int position) {
    ItemsAdapter itemAdapter = mList.get(position);
    ((ViewHolder) viewHolder).setUrduText.setText(itemAdapter.getUrdutext());
    ((ViewHolder) viewHolder).setEnglishText.setText(itemAdapter.getEnglishText());
    ((ViewHolder) viewHolder).setCleaningImage.setImageResource(itemAdapter.getImage());

    // Add this line
    ((ViewHolder) viewHolder).background.setBackgroundColor(Color.parseColor(&quot;default color&quot;));

    viewHolder.itemView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
             viewHolder.background.setBackgroundColor(Color.parseColor(&quot;#08A467&quot;));
        }
    });
}

答案2

得分: 2

这似乎很可能是RecyclerView的视图"回收"行为引起的问题。

通常,只有在onBindViewHolder()内部有一些仅在特定条件下设置的ViewHolder属性时,你才会遇到诸如这种问题。也就是说,由于并不总是更新ViewHolder的背景颜色,因此在它被回收和重用时会得到"错误"的颜色。

你需要以某种方式在项目列表中存储"已点击"或"已选择"的状态,然后在每次onBindViewHolder()中更新ViewHolder的背景颜色。可以类似这样:

@Override
public void onBindViewHolder(@NonNull AdapterOccupiedRoomCleaning.ViewHolder viewHolder, int position) {
    ItemsAdapter itemAdapter = mList.get(position);
    ...

    if (itemAdapter.isSelected()) {
        viewHolder.background.setBackgroundColor(Color.parseColor("#08A467"));
    } else {
        viewHolder.background.setBackgroundColor(Color.parseColor("#FFFFFF"));
    }

    viewHolder.itemView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            itemAdapter.setSelected(true);
            viewHolder.background.setBackgroundColor(Color.parseColor("#08A467"));
        }
    });
}

请注意,最好是在onCreateViewHolder()内部定义点击监听器,并使用notifyItemChanged()来更新背景颜色,而不是手动更新。不过,这超出了本问题的范围。

英文:

This seems likely to be a problem with the view recycling behavior of RecyclerView.

Generally, you're going to run into problems like this one any time you have some property of your ViewHolder that you only conditionally set inside onBindViewHolder(). That is, because you do not always update the background color of your ViewHolder, you'll get the "wrong" color when it is recycled and reused.

You will have to somehow store the "clicked" or "selected" state in your list of items, and then update the background color of your ViewHolder every time in onBindViewHolder(). Something like this:

@Override
public void onBindViewHolder(@NonNull AdapterOccupiedRoomCleaning.ViewHolder viewHolder, int position) {
    ItemsAdapter itemAdapter = mList.get(position);
    ...

    if (itemAdapter.isSelected()) {
        viewHolder.background.setBackgroundColor(Color.parseColor(&quot;#08A467&quot;));
    } else {
        viewHolder.background.setBackgroundColor(Color.parseColor(&quot;#FFFFFF&quot;));
    }

    viewHolder.itemView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            itemAdapter.setSelected(true);
            viewHolder.background.setBackgroundColor(Color.parseColor(&quot;#08A467&quot;));
        }
    });
}

Note that it would be better to define the click listener inside onCreateViewHolder() and to use notifyItemChanged() instead of manually updating the background color, but that's outside the scope of this question.

huangapple
  • 本文由 发表于 2020年10月14日 23:13:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/64356380.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定