【问题标题】:Android TransitionDrawable with multiple items具有多个项目的Android TransitionDrawable
【发布时间】:2013-03-27 10:38:59
【问题描述】:

我想在 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 中但这给出了完全相同的问题:-(

【问题讨论】:

  • TransitionDrawables 的文档中声明您可以指定 2 个以上的可绘制对象 - 您能提供一个链接到说明的地方吗?
  • developer.android.com/reference/android/graphics/drawable/… 这表明“此可绘制对象至少需要 2 层才能正常工作。”。正如我在原始帖子中所说,我还尝试了纯 Java 代码中的所有内容(因此实际上使用了这个构造函数),但这有完全相同的问题。
  • 单词的错误选择。我刚刚查看了TransitionDrawable 的代码,它只在两个可绘制对象之间淡入淡出,所有其他图层都被忽略了。
  • 感谢 Luksprog 在这种情况下,我会做一些变通方法来实现我想要的。
  • 也许你可以简单地使用两个TransitionDrawables,一个包含第一个和第二个drawable,另一个包含相同的第二个drawable和第三个drawable。

标签: java android


【解决方案1】:

您可以使用处理程序来做到这一点

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

【讨论】:

  • 完美!只有一件事 - 由于弃用,请考虑将 getDrawable 替换为 ContextCompat.getDrawable
【解决方案2】:

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

LayerDrawables 的扩展,旨在交叉淡入淡出 第一层和第二层。要开始过渡,请致电 开始过渡(int)。要仅显示第一层,请调用 重置过渡()。

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

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

【讨论】:

  • 实际上发生在我身上的是它可以很好地播放第一个过渡,然后当我再次调用 startTransition 时它会跳转到第一个可绘制对象并过渡回第二个。
  • 你是对的!我查看了文档并更新了答案。据记载,它仅适用于 2 层。
【解决方案3】:

在附录操作时间可以动态更换图片

在您的 TransitionDrawable

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

【讨论】:

    【解决方案4】:

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

    Here's 自定义TransitionDrawable 的现成实现可以处理两个以上的图像。

    您可以查看完整示例以及 gif 演示 here on Github

    【讨论】:

      【解决方案5】:

      您只需在每次迭代中创建一个新的 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-12-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-06-06
        • 1970-01-01
        • 1970-01-01
        • 2012-01-26
        • 2014-07-27
        相关资源
        最近更新 更多