选择器+转换组合在Android 4.2中无法正常工作

时间:2013-04-27 15:21:11

标签: android

我有一个符合以下要求的应用

  1. 在正常情况下,列表视图行的背景需要为白色
  2. 选择后,列表视图行的背景需要为蓝色
  3. 在2个列表视图行上执行动画,使其从红色转换为白色
  4. 似乎我可以利用选择器和过渡来解决这类问题。

    linear_layout_selector.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时,事情就破了。在正常情况下观察到以下情况。

    enter image description here

    1. 在正常情况下,从第2行开始,所有行都变为红色。
    2. 在正常情况下,第一行的背景仍为TransitionDrawable。然而,第二行和后续行的背景有神秘感变成了其他行。这可以从log
    3. 中看出
        

      WTF! 3rd currentDrawable是   android.graphics.drawable.LayerDrawable@b3068498

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

      我在想,这是一个错误吗?为什么TransitionDrawable可以成为LayerDrawable?有没有解决方法来解决这个问题?

      注意

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

1 个答案:

答案 0 :(得分:1)

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

我注意到克隆Drawable时发生的情况如下(我试图缓存并重新使用Drawable)。

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

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