如何在代码中使用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的代码部分开始(也就是注释掉纯编程代码行)。
如果您运行此代码并按下按钮,则会看到图像从trans1更改为trans4,而不是从trans3更改。为什么初始可绘制对象没有被替换?
整个setDrawableByLayerId()方法很令人困惑。在构造函数中,您需要指定一个Drawables列表,这些Drawables将进入一个LayerDrawable中。我认为这些就是所谓的索引。那么如果它不是这种索引,那么id又是什么呢?
我尝试向“item”标记添加android:id属性。虽然这段代码可以构建,但无法运行。因此,id不是通常使用的那个id。
也许它是该位置上当前可绘制对象的resId?这似乎也不对。
id似乎只是一些数字(可能在LayerDrawable中很重要),可以用setId(index,id)设置,并使用getId(index)获取。默认情况下,不会分配任何ID。并且您可以保留未添加图层的ID。在我的代码中,两个getId()调用都返回-1,这就是为什么使用setDrawableByLayerId(-1,...)仅有最后一个粘住的原因。确实,注释掉最后一行会产生不同的行为,从trans1到trans3的转换。
我如何更改第一个可绘制层?在setDrawableByLayerId()之前,我必须添加以下代码。即使我在任何地方都没有使用50或51。这将使它从trans3变为trans4。
transition.setId(0, 50);
transition.setId(1, 51);
我的概念有什么问题,以至于我必须让它变得如此复杂才能使其工作?
在我的实际应用程序中,我想做的是不使用任何xml代码,因为我认为它没有用处。我也想先添加第一层,只有在构建完成后再添加第二层,但我们稍后再继续。
让我们尝试纯编程代码。它是等效的。实际上,它立即放入了正确的可绘制对象。
现在,在这个示例应用程序中,它给出了相同的结果。然而,在我的应用程序中(其中相关代码过于复杂,无法在此处发布),我仍然有一个问题:
如果我尝试使用来自xml指定的转换的预编程可绘制对象,我会发现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,则会受到惩罚,因此我将只传入与第一个图层相同的可绘制对象。
我是否有遗漏的部分,或者还有更简单的方法可以完成这个任务?