web-dev-qa-db-ja.com

2つのimageview間のアニメーション遷移

一方で、2つのImageViewを備えたレイアウトがあります:

<FrameLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:tools="http://schemas.Android.com/tools"
    Android:id="@+id/container"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent" >

    <ImageView
        Android:id="@+id/image_cross2"
        Android:layout_width="wrap_content"
        Android:layout_height="@dimen/image_size"
        Android:layout_gravity="top"
        Android:scaleType="centerCrop" />

    <ImageView
        Android:id="@+id/image_cross1"
        Android:layout_width="wrap_content"
        Android:layout_height="@dimen/image_size"
        Android:layout_gravity="top"
        Android:scaleType="centerCrop" />
</FrameLayout>

一方、私は画像リソースのリストを持っています:

static int                      mImages[]               = new int[] {
        R.drawable.artistes,
        R.drawable.couple1,
        R.drawable.couple2,
        R.drawable.couple3,
        R.drawable.enfant,
        R.drawable.manege,
        R.drawable.manege2,
        R.drawable.metropolitain,
        R.drawable.panoramique,
        R.drawable.sacrecoeur               };

handler + postDelayed()で作成されたスケジューラーもあり、タイマーで画像を次々に表示します。これは正常に機能しています

私の問題は、あるイメージビューから別のイメージビューへの遷移アニメーションに関するものです。OutOfMemoryExceptionsを回避するために毎回イメージビューをクリーンアップする必要があります:

今のところ私はschduledコールバックメソッドでそれを行います:

if (mIndex == mImages.length) {
                    mIndex = 0; // repeat
                }
                if (mIndex % 2 != 0) { // pair
                    mImageCross2.setImageResource(mImages[mIndex++]);
                    Utils.crossfade(mImageCross2, mImageCross1, 1000/*duration*/);
                    mImageCross1.setImageResource(0);
                } else {
                    mImageCross1.setImageResource(mImages[mIndex++]);
                    Utils.crossfade(mImageCross1, mImageCross2, 1000);
                    mImageCross2.setImageResource(0);
                }

このアニメーションで:

public static void crossfade(final ImageView viewIn, final ImageView viewOut, int duration) {
        Animation fadeIn = new AlphaAnimation(0, 1);
        fadeIn.setDuration(duration);
        Animation fadeOut = new AlphaAnimation(1, 0);
        fadeOut.setDuration(duration);
        fadeOut.setAnimationListener(new AnimationListener() {

            @Override
            public void onAnimationStart(Animation animation) {
            }

            @Override
            public void onAnimationRepeat(Animation animation) {
            }

            @Override
            public void onAnimationEnd(Animation animation) {
                viewOut.setVisibility(View.GONE);
            }
        });
        fadeIn.setAnimationListener(new AnimationListener() {

            @Override
            public void onAnimationStart(Animation animation) {
            }

            @Override
            public void onAnimationRepeat(Animation animation) {
            }

            @Override
            public void onAnimationEnd(Animation animation) {
                viewIn.setVisibility(View.VISIBLE);
            }
        });
        viewOut.startAnimation(fadeOut);
        viewIn.startAnimation(fadeIn);
    }

アニメーションは素晴らしくなく、フェードは本当にスムーズではありません。毎回ImageViewをクリーンアップする必要があるときに、アニメーションをよりスムーズにするにはどうすればよいですか?

15
An-droid

私の最初の提案は、ほとんどのコードを単純化することです。 Androidには、この素敵な小さなクラスがあります TransitionDrawable

したがって、画像ビューを1つだけにして、TransitionDrawableを使用できます。

TransitionDrawable td = new TransitionDrawable( new Drawable[] {
    getResources().getDrawables(mImages[x]),
    getResources().getDrawables(mImages[y])
});
imageView.setImageDrawable(td);

tdのアニメーションを

td.startTransition(1000);
 // and
td.reverseTransition(1000);

postDelayedを使い続けてトリガーします

40
Budius