Can't Repro
Status Update
Comments
al...@android.com <al...@android.com>
ch...@google.com <ch...@google.com>
ki...@google.com <ki...@google.com> #2
Trying to reproduce this on my 4.2.2 (v17) Nexus 4. Added this drawable:
<transition xmlns:android="http://schemas.android.com/apk/res/android " >
<item android:drawable="@drawable/test_drawable_blue"/>
<item android:drawable="@drawable/test_drawable_green"/>
</transition>
where blue/green drawables look like this:
<shape
xmlns:android="http://schemas.android.com/apk/res/android "
android:shape="rectangle">
<size
android:width="@dimen/drawable_large_size"
android:height="@dimen/drawable_small_size" />
<solid
android:color="@color/test_blue" />
</shape>
Then added this test:
@Test
public void testMutateTransitionDrawable() {
Drawable drawable = ResourcesCompat.getDrawable(mResources,
R.drawable.test_transition_drawable, null);
assertTrue(drawable instanceof TransitionDrawable);
Drawable mutated = drawable.mutate();
assertTrue(drawable instanceof TransitionDrawable);
assertTrue(mutated instanceof TransitionDrawable);
}
It passes on the device. Going to also try on other earlier devices a bit later in the day once they are charged.
<transition xmlns:android="
<item android:drawable="@drawable/test_drawable_blue"/>
<item android:drawable="@drawable/test_drawable_green"/>
</transition>
where blue/green drawables look like this:
<shape
xmlns:android="
android:shape="rectangle">
<size
android:width="@dimen/drawable_large_size"
android:height="@dimen/drawable_small_size" />
<solid
android:color="@color/test_blue" />
</shape>
Then added this test:
@Test
public void testMutateTransitionDrawable() {
Drawable drawable = ResourcesCompat.getDrawable(mResources,
R.drawable.test_transition_drawable, null);
assertTrue(drawable instanceof TransitionDrawable);
Drawable mutated = drawable.mutate();
assertTrue(drawable instanceof TransitionDrawable);
assertTrue(mutated instanceof TransitionDrawable);
}
It passes on the device. Going to also try on other earlier devices a bit later in the day once they are charged.
ki...@google.com <ki...@google.com> #3
Also not reproducible on Galaxy Nexus running 4.0.1 (v14), 4.0.4 (v15) and 4.2.2 (v17)
Description
In the end i have found that the strange behaviour is caused by the mutate issue of Transition/LayerDrawable that has been fixed on api level 18.
This is the code that i'm using to solve the problem:
private static Drawable getDrawableCompat(Resources res, int id) {
Drawable d = ResourcesCompat.getDrawable(res, id, null);
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.JELLY_BEAN_MR1) {
// fix for "TransitionDrawable should not become a LayerDrawable"
//
// issue fixed on api 18+ (mr2) and that happens only on api 17 (mr1) because of the different
// drawable constantstate/mutate handling added on api 17
// "The drawables cache strikes again"
//
if (hasLayerDrawable(d)) {
d = d.getConstantState().newDrawable();
}
}
return d;
}
public static boolean hasLayerDrawable(Drawable d) {
if (d instanceof LayerDrawable) {
return true;
} else if (d instanceof DrawableContainer) {
final DrawableContainer.DrawableContainerState cs = (DrawableContainer.DrawableContainerState)d.getConstantState();
final Drawable[] children = cs.getChildren();
if (children != null) {
for (Drawable child : cs.getChildren()) {
if (child != null) {
if (hasLayerDrawable(child)) return true;
}
}
}
}
return false;
}