我正在使用Adapter
和RecyclerView
。我尝试更改RecyclerView
中第一项的颜色。我在onBindViewHolder
中执行了此操作,第一个确实更改了我想要的方式,但是如果我进一步查看8个视图,我会看到该视图也已更改。有点一致,项目编号0更改了,1,2,3,4不是5,6,7,8,9不是10等...
如果我去调试,我会发现我的if语句被触发了很多时间。如果我在互联网上搜索,我会看到人们使用相同的方式(在onBindViewHolder
中)。不知道我在做什么错:(
@Override
public void onBindViewHolder(@NonNull oScheduleAvailabilityViewHolder scheduleAvailabilityViewHolder, int position) {
oSchedule oSchedule = oScheduleArrayList.get(position);
scheduleAvailabilityViewHolder.scheduleAvailabilityTextView.setTypeface((oSchedule.getSelected()) ? Typeface.DEFAULT_BOLD : Typeface.SANS_SERIF);
scheduleAvailabilityViewHolder.scheduleAvailabilityTextView.setText(oSchedule.getScheduleName());
if (position == 0) {
scheduleAvailabilityViewHolder.scheduleAvailabilityTextView.setTextColor(0xFFd45155);
scheduleAvailabilityViewHolder.test.setBackgroundColor(0xFF1D3587);
}
}
我只希望更改颜色和背景的第一项(adapterPosition 0或位置0)。现在,其他视图的数量也相当稳定。
答案 0 :(得分:1)
尝试
在oSchedule类中,添加一个标志:
private boolean isFirstItem;
构造数据oScheduleArrayList时,设置第一项oSchedule.isFirstItem = true;
在适配器中:
@Override
public void onBindViewHolder(@NonNull oScheduleAvailabilityViewHolder scheduleAvailabilityViewHolder, int position) {
oSchedule oSchedule = oScheduleArrayList.get(position);
scheduleAvailabilityViewHolder.scheduleAvailabilityTextView.setTypeface((oSchedule.getSelected()) ? Typeface.DEFAULT_BOLD : Typeface.SANS_SERIF);
scheduleAvailabilityViewHolder.scheduleAvailabilityTextView.setText(oSchedule.getScheduleName());
if (oSchedule.isFirstItem) {
scheduleAvailabilityViewHolder.scheduleAvailabilityTextView.setTextColor(0xFFd45155);
scheduleAvailabilityViewHolder.test.setBackgroundColor(0xFF1D3587);
}
}
当您需要在活动中修改列表并刷新回收者视图时:
for (int i = 0; i < oScheduleArrayList.size(); i++) {
oScheduleArrayList.get(i).setIsFirstItem(i == 0);
}
adapter.notifyDataSetChanged();
好吧,我经常在使用recyclerview时修改UI的模型,因为它在外部适配器中是可管理的。但是,如果您只需要设置1个单元的UI,则使用Vinay的方法会更好。
答案 1 :(得分:0)
其他视图看起来像第一个项目的原因是因为当“回收”第一个项目作为第8个项目时,它保留了第一个项目的视图属性,除非您在绘制之前更改了它们。可以做类似的事情来解决它
public void onBindViewHolder(@NonNull oScheduleAvailabilityViewHolder scheduleAvailabilityViewHolder, int position) {
oSchedule oSchedule = oScheduleArrayList.get(position);
scheduleAvailabilityViewHolder.scheduleAvailabilityTextView.setTypeface((oSchedule.getSelected()) ? Typeface.DEFAULT_BOLD : Typeface.SANS_SERIF);
scheduleAvailabilityViewHolder.scheduleAvailabilityTextView.setText(oSchedule.getScheduleName());
if (position == 0) {
scheduleAvailabilityViewHolder.scheduleAvailabilityTextView.setTextColor(0xFFd45155);
scheduleAvailabilityViewHolder.test.setBackgroundColor(0xFF1D3587);
}else{
scheduleAvailabilityViewHolder.scheduleAvailabilityTextView.setTextColor(DEFAULT_COLOR_HERE);
scheduleAvailabilityViewHolder.test.setBackgroundColor(DEFAULT_COLOR_HERE);
}
另一种解决方案是对第一项和其余项使用不同的ItemType。 使用此技术,您可以创建不同的视图持有人(在您的情况下为两个),而回收者视图将仅回收给定项目类型的相应的(非第一项)。
答案 2 :(得分:0)
之所以发生这种情况,是因为适配器在滚动时再次使用了相同的itemView,并且您在项目位于位置0时更改了颜色,而在适配器再次使用时从未将其更改为默认颜色, 所以你要做的是
@Override
public void onBindViewHolder(@NonNull oScheduleAvailabilityViewHolder scheduleAvailabilityViewHolder, int position) {
oSchedule oSchedule = oScheduleArrayList.get(position);
scheduleAvailabilityViewHolder.scheduleAvailabilityTextView.setTypeface((oSchedule.getSelected()) ? Typeface.DEFAULT_BOLD : Typeface.SANS_SERIF);
scheduleAvailabilityViewHolder.scheduleAvailabilityTextView.setText(oSchedule.getScheduleName());
if (position == 0) {
scheduleAvailabilityViewHolder.scheduleAvailabilityTextView.setTextColor(0xFFd45155);
scheduleAvailabilityViewHolder.test.setBackgroundColor(0xFF1D3587);
}else{
//retutrn to deaftlt color
scheduleAvailabilityViewHolder.scheduleAvailabilityTextView.setTextColor(your deafult color);
scheduleAvailabilityViewHolder.test.setBackgroundColor(your deafult color);
}
}
答案 3 :(得分:0)
导致这种奇怪行为的行,
if (position == 0) {
scheduleAvailabilityViewHolder.scheduleAvailabilityTextView.setTextColor(0xFFd45155);
scheduleAvailabilityViewHolder.test.setBackgroundColor(0xFF1D3587);
}
每当您必须在recyclerView的if
方法中添加onBindViewHolder
条件时。切勿单独使用它。还要将其与else部分一起使用。
如果要在if
部分进行UI或数据更新,请在代码的else
部分将其恢复为正常。
if (position == 0) {
scheduleAvailabilityViewHolder.scheduleAvailabilityTextView.setTextColor(0xFFd45155);
scheduleAvailabilityViewHolder.test.setBackgroundColor(0xFF1D3587);
} else {
scheduleAvailabilityViewHolder.scheduleAvailabilityTextView.setTextColor({DEFAULT_COLOR});
scheduleAvailabilityViewHolder.test.setBackgroundColor({DEFAULT_COLOR});
}
如果您使用的是if (...) else if (...)
,这也会引起问题,因为当没有一个条件匹配时,UI会让我困惑。因此,始终将else ()
括号用作默认行为。即if (...) else if (...) else ()
。
注意:这适用于所有条件公式,例如switches
,when
等。
答案 4 :(得分:-1)
我认为这样可以更好地提高性能。每次创建/回收时,它只会触发第一项。
private static final int TYPE_AVAILABILITY = 1;
private static final int TYPE_WEEK = 2;
我以前在项目中曾经用过这种方式。
@Override
public void onBindViewHolder(@NonNull oScheduleAvailabilityViewHolder scheduleAvailabilityViewHolder, int position) {
oSchedule oSchedule = oScheduleArrayList.get(position);
scheduleAvailabilityViewHolder.scheduleAvailabilityTextView.setTypeface((oSchedule.getSelected()) ? Typeface.DEFAULT_BOLD : Typeface.SANS_SERIF);
scheduleAvailabilityViewHolder.scheduleAvailabilityTextView.setText(oSchedule.getScheduleName());
if (scheduleAvailabilityViewHolder.getItemViewType() == TYPE_AVAILABILITY) {
Log.i(TAG, "onBindViewHolder: TEST FIRST");
scheduleAvailabilityViewHolder.scheduleAvailabilityTextView.setTextColor(0xFFd45155);
scheduleAvailabilityViewHolder.test.setBackgroundColor(0xFF1D3587);
}
}
@Override
public int getItemViewType(int position) {
if (position == 0) {
return TYPE_AVAILABILITY;
} else {
return TYPE_WEEK;
}
}