Android RecyclerView如何更改第一个项目的文本颜色

时间:2019-06-25 07:53:13

标签: android recycler-adapter

我正在使用AdapterRecyclerView。我尝试更改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)。现在,其他视图的数量也相当稳定。

5 个答案:

答案 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 ()

注意:这适用于所有条件公式,例如switcheswhen等。

答案 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;
    }
}