【问题标题】:Color/drawable changes are applied to all views with the same background (color) [Marshmallow]颜色/可绘制更改应用于具有相同背景(颜色)的所有视图 [Marshmallow]
【发布时间】:2015-10-26 20:15:34
【问题描述】:

我最近将我的手机更新为 Android Marshmallow 并在其上运行我现有的应用程序,但注意到颜色行为有所不同:当将更改应用到视图(可绘制)的背景时,所有共享相同背景的视图(参考)也将应用相同的更改。而以前,情况并非如此。

示例
在此示例中,我有两个具有相同背景颜色的视图,并且我想更改两个视图之一的 alpha 级别。

首先我们在布局中定义视图:

    <LinearLayout
        android:id="@+id/test1"
        android:orientation="horizontal"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:background="@color/testColor2">

    </LinearLayout>

    <LinearLayout
        android:id="@+id/test2"
        android:orientation="horizontal"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:background="@color/testColor1"
        android:layout_marginLeft="5dp">
    </LinearLayout>

两个视图共享相同的背景颜色或可绘制对象:

<color name="testColor1">#3F51B5</color>
<color name="testColor2">#3F51B5</color>

结果如下所示:

现在我们要改变两个背景之一,像这样:

    LinearLayout test1 = (LinearLayout) findViewById(R.id.test1);
    LinearLayout test2 = (LinearLayout) findViewById(R.id.test2);
    test1.getBackground().setAlpha(80);

结果如下:

然而,期望和预期的结果显然是这样的:

下载示例项目here.

一些想法:

  • 通过 XML 设置 Alpha 级别时,此行为不适用。
  • 如果两个视图都在 colors.xml 中引用不同的颜色定义(如示例中),则无关紧要,直接在视图的 xml 文件中引用两者具有相同颜色(十六进制)的相同颜色定义。

问题
如何在不影响共享相同背景的其他视图的情况下更改视图的背景。 最好同时仍然能够使用直接引用颜色的 xml 文件中定义的颜色的背景

【问题讨论】:

  • “并将其复制到可绘制对象中”——这是什么意思?你有used mutate()吗?
  • 我用过:getConstantState().newDrawable();
  • 你能把每个视图的背景和常量状态的类转出,并检查它们是否是同一个对象吗?似乎这两种颜色资源已经在某个地方“合并”了——这意味着它们共享了 ConstantState。也许在资源类的缓存中?我本来希望它们保持分开,因为它们是不同的资源(尽管具有相同的颜色值),但显然不是。
  • 无论如何,ColorDrawable's state stores alpha,所以对其中一个的任何更改都会改变其他的。但是,像 @CommonsWare 推荐的那样,调用 mutate() 应该分离可绘制对象(通过复制状态)。

标签: android


【解决方案1】:

每个视图的背景和常量状态的类很可能是 同一个对象。好像这两种颜色资源已经 在某处“合并”——意味着他们共享了 ConstantState。也许在 资源类的缓存?我原以为他们会留下来 分开,因为它们是不同的资源(尽管颜色相同 值),但显然不是。

——Snild Dolkow

ColorDrawable 的状态存储 alpha,因此对其中一个的任何更改都会改变其他的。为防止这种情况,您可以首先在可绘制对象上调用 mutate(),将两个可绘制对象分开(通过复制状态)。

在示例中,这将导致使用 test1.getBackground().mutate().setAlpha(80); 而不是直接应用 alpha。

【讨论】:

  • 这似乎是关于这个的唯一帖子。在到处寻找解决方案之后,我终于要自己问了。然后 SO 提示 "Did you try these links" 终于将我指向这里。非常感谢! - 它拯救了我的一天:)
  • @gnB Google 本身有一篇关于此的非常好的文章。链接android-developers.googleblog.com/2009/05/…
  • 最后,这说明了一些问题。谢谢!
猜你喜欢
  • 2011-11-23
  • 1970-01-01
  • 1970-01-01
  • 2018-07-25
  • 2023-03-03
  • 1970-01-01
  • 1970-01-01
  • 2022-09-27
相关资源
最近更新 更多