英文:
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<AdapterOccupiedRoomCleaning.ViewHolder> {
private List<ItemsAdapter> mList;
private Context mContext;
public AdapterOccupiedRoomCleaning(List<ItemsAdapter> 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("#08A467"));
//
// Toast.makeText(mContext, "Recycle Click " + 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("#08A467"));
}
});
}
@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<ItemsAdapter> mList = new ArrayList<>();
private AdapterOccupiedRoomCleaning mAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_occupied_room_cleaning);
getQrCode = getIntent().getExtras().getString("qrcode");
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("sdf");
itemAdapter.setEnglishText("Pillow Parachute Cover Cleaning");
mList.add(itemAdapter);
itemAdapter = new ItemsAdapter();
itemAdapter.setImage(R.drawable.bedclean);
itemAdapter.setUrdutext("sdfs");
itemAdapter.setEnglishText("Patient Bed Cleaning(Blood Spots)");
mList.add(itemAdapter);
//... more items
}
private void adapter(){
Log.d("anhtt","mlist : " +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("default color"));
viewHolder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
viewHolder.background.setBackgroundColor(Color.parseColor("#08A467"));
}
});
}
答案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("#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"));
}
});
}
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论