Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Android TransitionDrawable具有多个项目_Java_Android - Fatal编程技术网

Java Android TransitionDrawable具有多个项目

Java Android TransitionDrawable具有多个项目,java,android,Java,Android,我想在Android中创建一个带有文本和背景图像的按钮。背景图像应每X一次交叉淡入淡出 我使用了一个带有2个图像的TransitionDrawable 但我不能让这个工作超过2个图像 我所拥有的: 在Java代码中,我创建了一个按钮并设置了一个背景(这是XML中定义的TransitionDrawable)。我开始过渡 final Button b = new Button(getApplicationContext()); b.setTextColor(getResources().getCol

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

我使用了一个带有2个图像的TransitionDrawable

但我不能让这个工作超过2个图像

我所拥有的:

在Java代码中,我创建了一个按钮并设置了一个背景(这是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个以上的drawables,但我无法实现这一点


我也尝试过不使用任何XML,但使用纯JAVA,但这带来了完全相同的问题:(

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

LayerDrawables的一个扩展,用于在 第一层和第二层。要开始转换,请调用 startTransition(int)。要仅显示第一层,请调用 resetTransition()

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


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

在附录操作时间中,你可以动态更改图片

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

TransitionDrawable transitionDrawable = (TransitionDrawable) myImage
                            .getDrawable();
transitionDrawable.setDrawableByLayerId(transitionDrawable.getId(1), getResources()
                            .getDrawable(R.drawable.c));

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

自定义
TransitionDrawable
的现成实现,用于处理两个以上的图像


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

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

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);

您只需在每次迭代中创建一个新的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);

}

在TransitionDrawables的文档中,您可以指定2个以上的drawables,您可以提供一个链接到其中的位置吗?这表示“至少需要2个层才能使这个drawables正常工作”。正如我在最初的帖子中所说的,我还尝试了纯Java代码中的所有内容(因此实际上使用了这个构造函数)但这也有完全相同的问题。用词不当。我刚刚查看了
TransitionDrawable
的代码,它只会在两个Drawable之间消失,其他层都会被忽略。谢谢Luksprog,在这种情况下,我会做一些变通来实现我想要的。也许你可以简单地使用两个TransitionDrawable,其中一个包含第一个和第二个可绘制文件,另一个包含相同的第二个可绘制文件和第三个可绘制文件。事实上,对我来说,第一个转换文件播放得很好,然后当我再次调用startTransition时,它跳转到第一个可绘制文件并转换回第二个。你说得对!我查看了文档并更新了ans文件被证明它只工作于2层。完美!只有一件事——由于弃用,考虑用CutExcPATAT.GETABLE替换GETabrabl。
handler.removeCallbacksAndMessages(null);