android UI:TransitionDrawable

时间:2010-12-30 23:13:03

标签: android user-interface transition

在代码中使用TransitionDrawable的目的是什么?有什么例子吗?

我制作了一个小型测试应用程序来制定一些背景信息:

public class SkeletonActivity extends Activity {
    private Button b;
    private ImageView iv;
    private TransitionDrawable transition;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Inflate our UI from its XML layout description.
        setContentView(R.layout.skeleton_activity);

        // Hook up button presses to the appropriate event handler.
        b = ((Button) findViewById(R.id.button));
        b.setOnClickListener(mButtonListener);
        iv = ((ImageView) findViewById(R.id.image));

        //XML-based code
        transition = (TransitionDrawable)getResources().getDrawable(R.drawable.trans).mutate();
        transition.setDrawableByLayerId(transition.getId(0), getResources().getDrawable(R.drawable.trans3));
        transition.setDrawableByLayerId(transition.getId(1), getResources().getDrawable(R.drawable.trans4));

        //Pure programmatic code
        transition = new TransitionDrawable(new Drawable[] {getResources().getDrawable(R.drawable.trans3), getResources().getDrawable(R.drawable.trans4)});

        transition.setCrossFadeEnabled(true);
    }

    OnClickListener mButtonListener = new OnClickListener() {
        public void onClick(View v) {
            iv.setImageDrawable(transition);
            transition.startTransition(5000);
        }
    };
}

和我的TransitionDrawable xml文件如下所示:

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

让我们首先从基于XML的代码部分开始(这意味着注释掉Pure编程代码行)。

如果您运行此代码并按下按钮,则会看到他的图像从trans1更改为trans4,而不是从trans3。为什么不替换最初的drawable?

整个setDrawableByLayerId()方法令人困惑。在构造函数中,您将指定一个进入LayerDrawable的Drawable列表。我想这些就是所谓的索引。如果它不是这样的索引,那么id是什么?

我尝试将android:id属性添加到“item”标签中。在构建此代码时,它不会运行。所以id不是你通常拥有的id。

也许这是当前那个职位上的抽奖人物?这似乎也没有。

Id似乎只是一些数字(可能在LayerDrawable中很重要),可以使用setId(index,id)设置并使用getId(index)获取。默认情况下,不分配任何ID。并且您可以为尚未添加的图层保留任何内容。在我的代码中,两个getId()调用都返回-1,这就是为什么当使用setDrawableByLayerId(-1,...)时,只有最后一个调用。确实评论出最后一行给出了不同的行为,给出了从trans1到trans3的过渡。

如何更改第一个可绘制图层?我必须在setDrawableByLayerId()之前添加以下代码。即使我不在任何地方使用50或51。这使得它从trans3变为trans4。

transition.setId(0, 50);
transition.setId(1, 51);

我的概念有什么问题,我必须让它变得复杂才能让它发挥作用?

我真正想在我的真实应用中做的不是使用任何xml代码,我认为没用。我还想首先添加第一层,然后才在构建之后添加到第二层,但我们将在稍后继续。

让我们试试纯编程代码。它是等价的。实际上它会立即放入正确的Drawables。

现在,在此示例应用程序中,它给出了相同的结果。但是,在我的应用程序中(其中相关代码太复杂而无法在此处发布),我仍有问题:

如果我尝试从xml指定的转换中预编程的Drawables,我得到getResources()。getDrawable(R.drawable.trans)第二次返回null:

12-30 21:35:32.970: ERROR/AndroidRuntime(7457): java.lang.NullPointerException
12-30 21:35:32.970: ERROR/AndroidRuntime(7457):     at android.graphics.drawable.LayerDrawable$LayerState.<init>(LayerDrawable.java:581)
12-30 21:35:32.970: ERROR/AndroidRuntime(7457):     at android.graphics.drawable.TransitionDrawable$TransitionState.<init>(TransitionDrawable.java:235)
12-30 21:35:32.970: ERROR/AndroidRuntime(7457):     at android.graphics.drawable.TransitionDrawable.createConstantState(TransitionDrawable.java:99)
12-30 21:35:32.970: ERROR/AndroidRuntime(7457):     at android.graphics.drawable.LayerDrawable.<init>(LayerDrawable.java:94)
12-30 21:35:32.970: ERROR/AndroidRuntime(7457):     at android.graphics.drawable.TransitionDrawable.<init>(TransitionDrawable.java:90)
12-30 21:35:32.970: ERROR/AndroidRuntime(7457):     at android.graphics.drawable.TransitionDrawable.<init>(TransitionDrawable.java:39)
12-30 21:35:32.970: ERROR/AndroidRuntime(7457):     at android.graphics.drawable.TransitionDrawable$TransitionState.newDrawable(TransitionDrawable.java:245)
12-30 21:35:32.970: ERROR/AndroidRuntime(7457):     at android.content.res.Resources.getCachedDrawable(Resources.java:1753)
12-30 21:35:32.970: ERROR/AndroidRuntime(7457):     at android.content.res.Resources.loadDrawable(Resources.java:1664)
12-30 21:35:32.970: ERROR/AndroidRuntime(7457):     at android.content.res.Resources.getDrawable(Resources.java:581)
12-30 21:35:32.970: ERROR/AndroidRuntime(7457):     at net.lp.collectionista.ui.views.CoverView.updateCover(CoverView.java:78)

我在这里缺少什么?缺少mutate()的东西?

我提到过我还想分两步设置图层,完全在代码中。意思是我首先要做的事情

transition = new TransitionDrawable(new Drawable[] {<1>});

仅传入一个图层。但是我不能在新图层上执行setId(),所以我以后不能添加新图层(尽管阅读setDrawableByLayerId()的文档会让你相信你可以)。

通过一个2的数组直接传递第二层,第二个元素为null,会受到惩罚,所以我只会传入与第一层相同的drawable。

我在这里遗失的任何东西都可以做得更轻松吗?

1 个答案:

答案 0 :(得分:4)

我建议只创建一个新的TransitionDrawable而不是“强奸”旧的。我一直这样做:

以下是我的代码片段,它为共享按钮创建了TransitionDrawable:

private TransitionDrawable createIconTransition( SharingStates layer1, SharingStates layer2 )
{
    Resources res = getContext().getResources();

    TransitionDrawable out = new TransitionDrawable( new Drawable[] { res.getDrawable( layer1.mIconId ), res.getDrawable( layer2.mIconId )} );
    out.setCrossFadeEnabled( true );

    return out;

}

然后致电:

mImageView.setImageDrawable( mTransitionDrawable );