Android RecyclerView中的图像回收不正确

Android RecyclerView中的图像回收不正确,android,imageview,android-recyclerview,porter-duff,Android,Imageview,Android Recyclerview,Porter Duff,我有一个RecyclerView,每行都有一个图标。图标应该是动态着色的,所以我使用白色图标并在绑定视图时应用颜色过滤器。奇怪的是,我最终得出的结论有很多不一致之处 在本例中,我试图使每三行变为红色,其余的变为绿色(注意#18): 下面是适配器。如您所见,每次重新绑定支架时,我都会将修改后的图标应用到ImageView,可能不会为旧的回收图像留下任何空间 public class TestAdapter extends RecyclerView.Adapter<TestAdapter.V

我有一个
RecyclerView
,每行都有一个图标。图标应该是动态着色的,所以我使用白色图标并在绑定视图时应用颜色过滤器。奇怪的是,我最终得出的结论有很多不一致之处

在本例中,我试图使每三行变为红色,其余的变为绿色(注意#18):

下面是适配器。如您所见,每次重新绑定支架时,我都会将修改后的图标应用到
ImageView
,可能不会为旧的回收图像留下任何空间

public class TestAdapter extends RecyclerView.Adapter<TestAdapter.ViewHolder> {

    private final Context context;

    public TestAdapter(Context context) {
        this.context = context;
    }

    @Override
    public TestAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_layout, parent, false);
        return new ViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(TestAdapter.ViewHolder holder, int position) {
        holder.bindItem(position);
    }

    @Override
    public int getItemCount() {
        return 200;
    }

    public class ViewHolder extends RecyclerView.ViewHolder {

        private final ImageView image;
        private final TextView text;

        public ViewHolder(View itemView) {
            super(itemView);

            image = (ImageView) itemView.findViewById(R.id.image);
            text = (TextView) itemView.findViewById(R.id.text);
        }

        public void bindItem(int position) {
            // pick color depending on the position
            final int color = ContextCompat.getColor(context,
                    position%3 == 0 ? android.R.color.holo_red_light : android.R.color.holo_green_light
            );

            // set text content and color
            text.setText("#" + position);
            text.setTextColor(color);

            // create icon from the resource and set filter
            final Drawable icon = ResourcesCompat.getDrawable(context.getResources(), R.drawable.ic_brightness, null);
            icon.setColorFilter(color, PorterDuff.Mode.MULTIPLY);

            image.setImageDrawable(icon);
        }
    }

}
有什么好处


谢谢。

尝试在bindview中使用此代码段

int color;
if(position%3 == 0){
    color = android.R.color.holo_red_light;
    text.setText("#" + position);
    text.setTextColor(color);
    Drawable icon = ResourcesCompat.getDrawable(context.getResources(), R.drawable.ic_brightness, null);
    icon.setColorFilter(color, PorterDuff.Mode.MULTIPLY);
    image.setImageDrawable(icon);

} else{
    color = android.R.color.holo_red_light;
    text.setText("#" + position);
    text.setTextColor(color);
    Drawable icon = ResourcesCompat.getDrawable(context.getResources(), R.drawable.ic_brightness, null);
    icon.setColorFilter(color, PorterDuff.Mode.MULTIPLY);
    image.setImageDrawable(icon);
}

看过你的评论后,我不确定这是否适合你的要求。但是,我可以通过在布局文件中使用
android:src
元素设置“亮度”可绘制,然后将过滤器应用于
ImageView
(而不是图标),来复制预期的行为:


如果您想拥有不同类型的视图,而不是选择位置,请考虑重写
getItemViewType
方法。问题是在实际项目中,颜色可能是任意的,它来自服务器。这很有趣。你有没有用不同的图标而不是过滤器来测试过,看你是否仍能得到相同的结果?@PPartisan是的,不同的图标都能正常工作。谢谢,但逻辑基本相同。不幸的是,问题仍然存在。谢谢,它工作得很好!与此同时,我开始阅读
BitmapDrawable
的源代码,偶然发现了一条非常有用的评论:“可变BitmapDrawable仍然与来自同一资源的任何其他Drawable共享其位图”。因此,另一个有效的方法是在设置
setColorFilter()
之前调用
icon=icon.mutate()
,但我更喜欢您的解决方案。
int color;
if(position%3 == 0){
    color = android.R.color.holo_red_light;
    text.setText("#" + position);
    text.setTextColor(color);
    Drawable icon = ResourcesCompat.getDrawable(context.getResources(), R.drawable.ic_brightness, null);
    icon.setColorFilter(color, PorterDuff.Mode.MULTIPLY);
    image.setImageDrawable(icon);

} else{
    color = android.R.color.holo_red_light;
    text.setText("#" + position);
    text.setTextColor(color);
    Drawable icon = ResourcesCompat.getDrawable(context.getResources(), R.drawable.ic_brightness, null);
    icon.setColorFilter(color, PorterDuff.Mode.MULTIPLY);
    image.setImageDrawable(icon);
}
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> {

    public RecyclerViewAdapter() {
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
        View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.rv_row, viewGroup, false);
        return new ViewHolder(v);
    }

    @Override
    public void onBindViewHolder(ViewHolder viewHolder, int i) {
        viewHolder.bindItem(i);
    }

    @Override
    public int getItemCount() {
        return 200;
    }

    public static class ViewHolder extends RecyclerView.ViewHolder {

        private final ImageView image;
        private final TextView text;

        public ViewHolder(View itemView) {
            super(itemView);

            image = (ImageView) itemView.findViewById(R.id.image);
            text = (TextView) itemView.findViewById(R.id.text);
        }

        public void bindItem(int position) {

            final int color = ContextCompat.getColor(itemView.getContext(),
                    position % 3 == 0 ? android.R.color.holo_red_light : android.R.color.holo_green_light
            );

            text.setText("#" + position);
            text.setTextColor(color);

            image.setColorFilter(color, PorterDuff.Mode.MULTIPLY);
        }
    }
}
public static class ViewHolder extends RecyclerView.ViewHolder {

    private final ImageView image;
    private final TextView text;

    public ViewHolder(View itemView) {
        super(itemView);

        image = (ImageView) itemView.findViewById(R.id.image);
        text = (TextView) itemView.findViewById(R.id.text);
    }

    public void bindItem(int position) {

        final int color = ContextCompat.getColor(itemView.getContext(),
                position % 3 == 0 ? android.R.color.holo_red_light : android.R.color.holo_green_light
        );

        text.setText("#" + position);
        text.setTextColor(color);

        Drawable icon = getIcon();

        image.setImageDrawable(icon);
        image.setColorFilter(color, PorterDuff.Mode.MULTIPLY);
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    private Drawable getIcon() {
        return (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
                ? image.getContext().getResources().getDrawable(R.drawable.ic_brightness_1_white_24dp, null)
                : image.getContext().getResources().getDrawable(R.drawable.ic_brightness_1_white_24dp);
    }
}