14

我想在 Android 中创建一个带有文本和背景图像的按钮。背景图像应每 X 次淡入淡出。

我使用带有 2 个图像的 TransitionDrawable 进行这项工作。

但我不能让它处理超过 2 个图像。

我有的 :

在 Java 代码中,我创建了一个 Button 并设置了一个背景(这是一个在 XML 中定义的 TransitionDrawable)。我开始过渡。

final Button b = new Button(getApplicationContext());
b.setTextColor(getResources().getColor(R.color.white));
b.setText("Some text");
b.setBackgroundDrawable(getResources().getDrawable(R.drawable.tile));
StateListDrawable background = (StateListDrawable) b.getBackground();
TransitionDrawable td = (TransitionDrawable) background.getCurrent();
td.startTransition(2000);

在 XML 我在 tile.xml 中定义

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true" >
        <shape>
            <solid
                android:color="#449def" />
        </shape>
    </item>
    <item android:drawable="@drawable/transition">
        <shape>
            <solid
                android:color="#0000ff" />
        </shape>
    </item>
</selector> 

最后是一个transition.xml

<?xml version="1.0" encoding="utf-8"?>
<transition xmlns:android="http://schemas.android.com/apk/res/android"     android:oneshot="false">
  <item android:drawable="@drawable/desert"/> 
  <item android:drawable="@drawable/hydrangeas" /> 
  <item android:drawable="@drawable/jellyfish" /> 
</transition> 

现在的效果是,当我启动应用程序时,会显示沙漠图像。该图像按应有的方式淡入绣球花图像。但是从未显示过水母图像。

在 TransitionDrawables 的文档中,声明您可以指定超过 2 个可绘制对象,但我无法使其正常工作。

我也试过这个没有任何 XML 但在纯 JAVA 中但这给出了完全相同的问题:-(

4

5 回答 5

7

您可以使用处理程序来完成

mAnimateImage is your button

int DrawableImage[] = {R.drawable.back_red, R.drawable.back_green, R.drawable.back_purple};

final Handler handler = new Handler();
    final int[] i = {0};
    final int[] j = {1};
    handler.postDelayed(new Runnable() {
        @Override
        public void run() {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    Resources res = getApplicationContext().getResources();
                    TransitionDrawable out = new TransitionDrawable(new Drawable[]{res.getDrawable(DrawableImage[i[0]]), res.getDrawable(DrawableImage[j[0]])});
                    out.setCrossFadeEnabled(true);
                    mAnimateImage.setBackgroundDrawable(out);
                    out.startTransition(4000);
                    i[0]++;
                    j[0]++;
                    if (j[0] == DrawableImage.length) {
                        j[0] = 0;
                    }
                    if (i[0] == DrawableImage.length) {
                        i[0] = 0;
                    }
                    handler.postDelayed(this, 8000);
                }
            });
        }
    }, 0);
于 2016-08-05T11:04:56.890 回答
6

根据官方文档,TransitionDrawable 只能在 2 层之间交叉淡入淡出,引用自官方 android 参考。

LayerDrawables 的扩展,旨在在第一层和第二层之间交叉淡入淡出。要开始转换,请调用 startTransition(int)。要仅显示第一层,请调用 resetTransition()。

如果你不仔细阅读它,因为它扩展了 LayerDrawables,它可以有多个层,你可能会认为你可以从 N 层交叉淡入淡出。但是很清楚,startTransition 显示第二层,resetTransition 显示第一层。

我建议你自己实现多个转换。我要做的是拥有 2 张图像并为它们设置动画。您可能需要手动设置可绘制对象,但它应该是一段非常简单的代码。

于 2013-07-23T09:44:54.483 回答
4

在附录操作时间可以动态改变图片

在您的TransitionDrawable上使用td.setDrawableByLayerId(td.getId(1), drawable)

TransitionDrawable transitionDrawable = (TransitionDrawable) myImage
                            .getDrawable();
transitionDrawable.setDrawableByLayerId(transitionDrawable.getId(1), getResources()
                            .getDrawable(R.drawable.c));
于 2013-11-09T12:43:27.560 回答
1

您最多只能使用 转换两个图像TransitionDrawable。要处理两个以上的图像,您可以扩展 LayerDrawable 并实现自己的TransitionDrawable.

是自定义的现成实现,TransitionDrawable可以处理两个以上的图像。

您可以在 Github 上看到完整的示例以及 gif 演示。

于 2016-07-24T11:11:19.097 回答
-1

您只需在每次迭代中创建一个新的 TransitionDrawable。

这将逐步增加您添加的所有图像的索引,您可以拥有任意数量的图像......

private Handler handler = new Handler();

private void startImageCrossfading(@IdRes int imageViewResId, @DrawableRes int... drawableIds) {

    Drawable[] bitmapDrawables = new Drawable[drawableIds.length];

    for (int i = 0; i < drawableIds.length; i++) {
        // if you are using Vectors cross fade won't work unless you do this! - See my answer at https://stackoverflow.com/a/54583929/114549
        // bitmapDrawables[i] = getBitmapDrawableFromVectorDrawable(this, drawableIds[i]);
        bitmapDrawables[i] = ContextCompat.getDrawable(this, drawableIds[i]);
    }

    final ImageView imageView = findViewById(imageViewResId);

    handler.postDelayed(new Runnable() {
        int index = 0;
        @Override
        public void run() {

            TransitionDrawable td = new TransitionDrawable(new Drawable[]{
                    bitmapDrawables[index % bitmapDrawables.length],
                    bitmapDrawables[++index % bitmapDrawables.length]
            });
            td.setCrossFadeEnabled(true);
            imageView.setImageDrawable(td);

            td.startTransition(500); // transitionDurationMillis
            handler.postDelayed(this, 3000);
        }
    }, 3000);

}

暂停时,您应该清理处理程序

handler.removeCallbacksAndMessages(null);
于 2019-02-07T23:49:10.920 回答