14

テキストと背景画像を使用して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つ以上のドローアブルを指定できると記載されていますが、これを機能させることはできません。

私も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は、公式のAndroidリファレンスから引用して、2つのレイヤー間でのみクロスフェードできます。

1番目のレイヤーと2番目のレイヤーの間でクロスフェードすることを目的としたLayerDrawablesの拡張。遷移を開始するには、startTransition(int)を呼び出します。最初のレイヤーだけを表示するには、resetTransition()を呼び出します。

注意深く読まないと、複数のレイヤーを持つことができるLayerDrawablesが拡張されるため、Nレイヤーからクロスフェードする可能性があると予想される場合があります。しかし、それは非常に明確です。startTransitionは2番目のレイヤーを示し、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

遷移できるのは、最大2つの画像のみTransitionDrawableです。3つ以上の画像を操作するには、LayerDrawableを拡張して、独自の画像を実装できますTransitionDrawable

TransitionDrawableこれは、3つ以上の画像を処理するためのカスタムの実装です

完全なサンプルとgifデモは、ここGithubで見ることができます。

于 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 に答える