【问题标题】:Android RecyclerView not changing background color on first item programmaticallyAndroid RecyclerView不会以编程方式更改第一项的背景颜色
【发布时间】:2016-12-30 00:10:23
【问题描述】:

我正在创建一个带有RecyclerView 的列表。 每个列表项都是来自用户的帖子(现在是硬编码)。 每个帖子的背景都是从可绘制文件夹中的layer-list XML 文件加载的。

文本等一切都按预期工作,但我正在尝试以编程方式更改背景颜色。它改变了每个项目的背景颜色,除了是第一个项目,我不知道为什么。

第一项总是获取XML文件中称为shape_backgrounditem里面的shapesolid指定的背景颜色,所以没有改变,但是后面的各项获取颜色#ff22ff.

这是适配器的实现:

class PostListAdapter extends RecyclerView.Adapter<PostListAdapter.PostViewHolder>{

    private LayoutInflater inflater;
    private List<PostRow> data = Collections.emptyList();

    PostListAdapter(Context context, List<PostRow> data) {
        inflater = LayoutInflater.from(context);
        this.data = data;
    }

    @Override
    public void onBindViewHolder(PostViewHolder holder, int position) {

        PostRow current = data.get(position);
        holder.text.setText(current.text.toUpperCase());
        holder.time.setText(current.time.toUpperCase());
        holder.answers.setText(current.answers.toUpperCase());

        try {
            // "#ff22ff" will be changed to current.color, unique color for every post
            // That string is parsed from a JSON request, hence the try-catch.
            int color = Color.parseColor("#ff22ff"); 
            holder.shape.setColor(color);
        } catch (Exception e){
            e.printStackTrace();
        }

    }

    @Override
    public PostViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = inflater.inflate(R.layout.post_row, parent, false);
        return new PostViewHolder(view);
    }

    @Override
    public int getItemCount() {
        return data.size();
    }

    class PostViewHolder extends RecyclerView.ViewHolder {

        TextView text;
        TextView time;
        TextView answers;
        GradientDrawable shape;

        PostViewHolder(View itemView) {
            super(itemView);
            text = (TextView) itemView.findViewById(R.id.text);
            time = (TextView) itemView.findViewById(R.id.time);
            answers = (TextView) itemView.findViewById(R.id.answers);
            LayerDrawable layers = (LayerDrawable) ContextCompat.getDrawable(itemView.getContext(), R.drawable.bubble);

            shape = (GradientDrawable) (layers.findDrawableByLayerId(R.id.shape_background));
        }

    }

}

为什么第一项的背景没有变,文字却变了?

提前谢谢你!

【问题讨论】:

  • 你有什么异常吗?为什么要尝试捕捉?
  • 我知道评论不够清楚。硬编码字符串“#ff22ff”稍后将更改为字符串 current.color。该字符串是从 JSON 响应中解析的。因此,以防万一在该过程中出现问题,请使用 try-catch 将其包围。我会更新评论,谢谢。

标签: android android-recyclerview shape layer-list gradientdrawable


【解决方案1】:

在您的onBindViewHolder 上,获取您需要更改背景颜色的视图(来自持有人)并获取其当前背景(可绘制气泡,您已在 XML 属性中设置)

LayerDrawable layerDrawable = (LayerDrawable) yourView.getBackground().getCurrent();
GradientDrawable gradientDrawable = (GradientDrawable) layerDrawable.findDrawableByLayerId(R.id. shape_background).getCurrent();
// set you color based on position
gradientDrawable.setColor(Color.parseColor("#ff22ff"));

【讨论】:

  • 谢谢,这以我想要的方式解决了我的问题。使用 API 15 及更高版本,所以在我的情况下不能使用 liubaoyua 的答案中的 setBackground,但它也是正确的。
【解决方案2】:

您已致电holder.shape.setColor(color);

但是 holderView 没有刷新。

也许你应该打电话给

holder.itemView.setBackgroundDrawable( ContextCompat.getDrawable(itemView.getContext(), R.drawable.bubble))

刷新 holderView

【讨论】:

  • 这是正确的,但请注意 setBackgroundDrawable 已被弃用。即使 setBackground 调用 setBackgroundDrawable 方法,也应该为 API 级别 16 及更高级别使用 setBackground。
【解决方案3】:

这里有两个不同的问题。

首先 - 您更改可绘制对象本身但不更改视图背景。由 liubaoyua 和 Vignesh Sundar 解答。

第二 - 你静态地改变 R.drawable.bubble。即使在突变之后,Android 也可以缓存和重用它。当您开始为不同的项目使用不同的颜色时,可能会导致另一个问题。

要解决第二个问题,您必须在第一次变异之前每次调用android.graphics.drawable.Drawable#mutate

默认情况下,从同一资源加载的所有可绘制实例共享一个公共状态;如果您修改一个实例的状态,所有其他实例都将收到相同的修改。

所以它应该看起来像这样:

class PostViewHolder extends RecyclerView.ViewHolder {

    TextView text;
    TextView time;
    TextView answers;
    LayerDrawable layers;
    GradientDrawable shape;

    PostViewHolder(View itemView) {
        super(itemView);

        text = (TextView) itemView.findViewById(R.id.text);
        time = (TextView) itemView.findViewById(R.id.time);
        answers = (TextView) itemView.findViewById(R.id.answers);

        layers = (LayerDrawable) ContextCompat
                .getDrawable(itemView.getContext(), R.drawable.bubble)
                .mutate();

        shape = (GradientDrawable) layers.findDrawableByLayerId(R.id.shape_background);
        itemView.setBackground(layers);
    }

    void setColor(Color color) {
        shape.setColor(color);
        itemView.setBackgroundDrawable(layers);
    }
}

可以通过将.mutate() 从层移动到形状来稍微简化。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-21
    • 1970-01-01
    • 2020-10-31
    相关资源
    最近更新 更多