我最近将手机更新为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文件中定义的颜色的背景
答案 0 :(得分:16)
每个视图的背景和恒定状态的类很可能是 同一个对象。好像两种颜色资源一样 “合并”某处 - 意味着他们共享了ConstantState。也许在 Resources类的缓存?我希望他们留下来 因为它们是不同的资源(尽管颜色相同) 价值),但显然不是。
ColorDrawable的状态存储alpha,因此对one的任何更改都会更改其他的。为了防止这种情况,你可以先在drawable上调用mutate(),将两个drawable分开(通过制作一个状态的副本)。
在示例中,这将导致使用test1.getBackground().mutate().setAlpha(80);
而不是直接应用alpha。