0

我有一个具有以下要求的应用程序

  1. 正常情况下,列表视图行的背景需要为白色
  2. 选中时,列表视图行的背景需要为蓝色
  3. 对 2 个列表视图行执行动画,使它们从red过渡到white

看来我可以利用选择器和转换来解决这种问题。

线性布局选择器.xml

<?xml version="1.0" encoding="utf-8"?>    
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true" android:drawable="@drawable/blue" />

    <item android:drawable="@drawable/linear_layout_transition" />
</selector>

linear_layout_transition.xml

<?xml version="1.0" encoding="utf-8"?>
<transition xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/white" />
    <item android:drawable="@drawable/red" />
</transition>

simple_list_item_1.xml

<?xml version="1.0" encoding="utf-8"?>

<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/text1"
    android:layout_width="match_parent"
    android:layout_height="48dp"
    android:background="@drawable/linear_layout_selector"
/>

执行动画的 Java 代码

{
    // Animate 1st row.
    View view0 = this.getListView().getChildAt(0);
    StateListDrawable stateListDrawable = (StateListDrawable)view0.getBackground();    
    Drawable currentDrawable = stateListDrawable.getCurrent();
    if (currentDrawable instanceof TransitionDrawable) {
        final TransitionDrawable transitionDrawable = (TransitionDrawable) currentDrawable;
        transitionDrawable.resetTransition();
        transitionDrawable.startTransition(0);
        transitionDrawable.reverseTransition(1000);
    } else {
        Log.i("CHEOK", "WTF! 1st currentDrawable is " + currentDrawable);
    }
}
{
    // Animate 3rd row.
    View view2 = this.getListView().getChildAt(2);
    StateListDrawable stateListDrawable = (StateListDrawable)view2.getBackground();    
    Drawable currentDrawable = stateListDrawable.getCurrent();
    if (currentDrawable instanceof TransitionDrawable) {
        final TransitionDrawable transitionDrawable = (TransitionDrawable) currentDrawable;
        transitionDrawable.resetTransition();
        transitionDrawable.startTransition(0);
        transitionDrawable.reverseTransition(1000);
    } else {
        Log.i("CHEOK", "WTF! 3rd currentDrawable is " + currentDrawable);
    }
}

一切都在 Android 4.1 和 Android 2.3.3 中正常工作

然而,当谈到 Android 4.2 时,事情就坏了。在正常情况下观察到以下情况。

在此处输入图像描述

  1. 正常情况下,从第 2 行开始,所有行都变成红色。
  2. 正常情况下,第一排的背景仍然保持不变TransitionDrawable。然而,第二排及之后的几排的背景却变得神秘了起来。这可以从日志中看出

哇!第三个 currentDrawable 是 android.graphics.drawable.LayerDrawable@b3068498

可以从这里下载演示此问题的完整项目:https ://www.dropbox.com/s/hbalqjzzw5tu7e9/transition_bug.zip

我想知道,这是一个错误吗?为什么一个TransitionDrawable可以成为LayerDrawable?有什么解决方法可以克服这个问题吗?

笔记

如果我linear_layout_transition直接应用为TextView的背景,问题就会消失。但是,我将失去选择器提供的功能。

4

1 回答 1

1

这似乎是 JellyBean 中的一个错误。Resources#getDrawable(int)将在第一个请求上返回正确的类型 ( TransitionDrawable),但在任何连续请求上都会返回错误的类型(在这种情况下LayerDrawable)。

我注意到在克隆Drawable以下内容时也会发生同样的情况(我试图自己缓存和重用Drawable)。

Drawable clonedDrawable = backgroundDrawable.getConstantState().newDrawable();
convertView.setBackgroundDrawable(clonedDrawable);

您可以通过将选择器设置为 ListView ( ListView#setSelector(int)) 并将 设置TransitionDrawable为列表项 ( convertView) 的背景来解决此问题。

于 2013-07-22T15:29:49.887 回答