如何始终如一地向 RecyclerView 中的项目视图添加交替背景
How to consistently add alternating backgrounds to item views in RecyclerView
到目前为止,我使用适配器的 onBindViewHolder
根据项目的适配器位置设置交替背景。
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.itemView.setBackgroundResource(position % 2 == 0 ?
R.color.list_item_background_alternating : R.color.list_item_background);
...
}
但是,如果不仅仅是显示列表,这会变得越来越复杂。
例如:当我删除一个项目并调用 notifyItemRemoved(index);
时,RecyclerView
会执行一个很好的动画并且项目视图消失了。但是,替换已删除视图的视图不会再次绑定(出于明显和充分的理由),因此保留了它的旧背景。这导致与布局不一致并且看起来很难看。当我调用 notifyDataSetChanged();
时,背景都是正确的,但我失去了动画。
我在使用 SortedList
(带有 SortedListAdapterCallback
)时遇到了类似的问题。由于排序似乎是在视图绑定之后进行的,因此背景一团糟。
实施此类行为的 proper/consistent 方法是什么?
好吧,当我写下我的问题时,我想尝试一件我认为行不通的事情 - 然而,它确实行得通。
我创建了一个 ItemDecoration
并使用它的 getItemOffset();
来设置视图的背景:
public class BackgroundItemDecoration extends RecyclerView.ItemDecoration {
private final int mOddBackground;
private final int mEvenBackground;
public BackgroundItemDecoration(@DrawableRes int oddBackground, @DrawableRes int evenBackground) {
mOddBackground = oddBackground;
mEvenBackground = evenBackground;
}
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
super.getItemOffsets(outRect, view, parent, state);
int position = parent.getChildAdapterPosition(view);
view.setBackgroundResource(position % 2 == 0 ? mEvenBackground : mOddBackground);
}
}
虽然我有点内疚,我在 getItemOffsets()
上偷懒。
有人有 cleaner/better 解决方案吗?
这是我的解决方案
itemView 是指 onCreateViewHolder 中 Layout inflater 中的 View。
public void onBindViewHolder(MyViewHolder holder, int position){
//alternate row color
if(position % 2==0)
holder.itemView.setBackgroundColor(Color.YELLOW);
else
holder.itemView.setBackgroundColor(Color.LTGRAY);
)
这就是您所需要的。希望这有帮助。
注意:- 此代码适用于 Lollipop 及更高版本的测试。并填写您的构造函数 get context is not null 如果它为 null 则它不起作用。
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
LocationModel locationModel = locationModelArrayList.get(position);
if(position%2==0)
{
holder.itemView.setBackgroundColor(ContextCompat.getColor(context,R.color.colorPrimary));
}else
{
holder.itemView.setBackgroundColor(ContextCompat.getColor(context,R.color.colorPrimaryDark));
}
}
到目前为止,我使用适配器的 onBindViewHolder
根据项目的适配器位置设置交替背景。
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.itemView.setBackgroundResource(position % 2 == 0 ?
R.color.list_item_background_alternating : R.color.list_item_background);
...
}
但是,如果不仅仅是显示列表,这会变得越来越复杂。
例如:当我删除一个项目并调用 notifyItemRemoved(index);
时,RecyclerView
会执行一个很好的动画并且项目视图消失了。但是,替换已删除视图的视图不会再次绑定(出于明显和充分的理由),因此保留了它的旧背景。这导致与布局不一致并且看起来很难看。当我调用 notifyDataSetChanged();
时,背景都是正确的,但我失去了动画。
我在使用 SortedList
(带有 SortedListAdapterCallback
)时遇到了类似的问题。由于排序似乎是在视图绑定之后进行的,因此背景一团糟。
实施此类行为的 proper/consistent 方法是什么?
好吧,当我写下我的问题时,我想尝试一件我认为行不通的事情 - 然而,它确实行得通。
我创建了一个 ItemDecoration
并使用它的 getItemOffset();
来设置视图的背景:
public class BackgroundItemDecoration extends RecyclerView.ItemDecoration {
private final int mOddBackground;
private final int mEvenBackground;
public BackgroundItemDecoration(@DrawableRes int oddBackground, @DrawableRes int evenBackground) {
mOddBackground = oddBackground;
mEvenBackground = evenBackground;
}
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
super.getItemOffsets(outRect, view, parent, state);
int position = parent.getChildAdapterPosition(view);
view.setBackgroundResource(position % 2 == 0 ? mEvenBackground : mOddBackground);
}
}
虽然我有点内疚,我在 getItemOffsets()
上偷懒。
有人有 cleaner/better 解决方案吗?
这是我的解决方案 itemView 是指 onCreateViewHolder 中 Layout inflater 中的 View。
public void onBindViewHolder(MyViewHolder holder, int position){
//alternate row color
if(position % 2==0)
holder.itemView.setBackgroundColor(Color.YELLOW);
else
holder.itemView.setBackgroundColor(Color.LTGRAY);
)
这就是您所需要的。希望这有帮助。
注意:- 此代码适用于 Lollipop 及更高版本的测试。并填写您的构造函数 get context is not null 如果它为 null 则它不起作用。
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
LocationModel locationModel = locationModelArrayList.get(position);
if(position%2==0)
{
holder.itemView.setBackgroundColor(ContextCompat.getColor(context,R.color.colorPrimary));
}else
{
holder.itemView.setBackgroundColor(ContextCompat.getColor(context,R.color.colorPrimaryDark));
}
}