Android使用ImageView淡入淡出

IPV*_*rde 85 animation android fadeout fadein imageview

我正在制作幻灯片,我遇到了一些麻烦.

我在xml中创建了2个动画,用于淡入和淡出:

fadein.xml

    <?xml version="1.0" encoding="UTF-8"?>
       <set xmlns:android="http://schemas.android.com/apk/res/android">
         <alpha android:fromAlpha="0.0" android:toAlpha="1.0" 
          android:interpolator="@android:anim/accelerate_interpolator" 
          android:duration="2000"/>
     </set>
Run Code Online (Sandbox Code Playgroud)

fadeout.xml

    <?xml version="1.0" encoding="UTF-8"?>
       <set xmlns:android="http://schemas.android.com/apk/res/android">
         <alpha android:fromAlpha="1.0" android:toAlpha="0.0" 
          android:interpolator="@android:anim/accelerate_interpolator" 
          android:duration="2000"/>
     </set>
Run Code Online (Sandbox Code Playgroud)

我正在做的是使用淡入淡出效果从ImageView更改图像,因此当前显示的图像将淡出,另一个将淡入.考虑到我已经设置了图像,我可以淡出此图像而不用问题,这个:

    Animation fadeInAnimation = AnimationUtils.loadAnimation(this, R.anim.your_fade_in_anim);
    imageView.startAnimation(fadeoutAnim);
Run Code Online (Sandbox Code Playgroud)

但是,我设置下一个要显示的图像:

    imageView.setImageBitmap(secondImage);
Run Code Online (Sandbox Code Playgroud)

它只是出现在imageView中,当我设置动画时它会隐藏图像,淡入它...有没有办法解决它,我的意思是,当我做imageView.setImageBitmap(secondImage); 命令,图像不会立即显示,只有当淡入动画执行时?

Cro*_*ile 96

我想实现与你相同的目标,所以我编写了以下方法,如果你传递一个ImageView和一个对图像drawables的引用列表,我就会这样做.

ImageView demoImage = (ImageView) findViewById(R.id.DemoImage);
int imagesToShow[] = { R.drawable.image1, R.drawable.image2,R.drawable.image3 };

animate(demoImage, imagesToShow, 0,false);  



  private void animate(final ImageView imageView, final int images[], final int imageIndex, final boolean forever) {

  //imageView <-- The View which displays the images
  //images[] <-- Holds R references to the images to display
  //imageIndex <-- index of the first image to show in images[] 
  //forever <-- If equals true then after the last image it starts all over again with the first image resulting in an infinite loop. You have been warned.

    int fadeInDuration = 500; // Configure time values here
    int timeBetween = 3000;
    int fadeOutDuration = 1000;

    imageView.setVisibility(View.INVISIBLE);    //Visible or invisible by default - this will apply when the animation ends
    imageView.setImageResource(images[imageIndex]);

    Animation fadeIn = new AlphaAnimation(0, 1);
    fadeIn.setInterpolator(new DecelerateInterpolator()); // add this
    fadeIn.setDuration(fadeInDuration);

    Animation fadeOut = new AlphaAnimation(1, 0);
    fadeOut.setInterpolator(new AccelerateInterpolator()); // and this
    fadeOut.setStartOffset(fadeInDuration + timeBetween);
    fadeOut.setDuration(fadeOutDuration);

    AnimationSet animation = new AnimationSet(false); // change to false
    animation.addAnimation(fadeIn);
    animation.addAnimation(fadeOut);
    animation.setRepeatCount(1);
    imageView.setAnimation(animation);

    animation.setAnimationListener(new AnimationListener() {
        public void onAnimationEnd(Animation animation) {
            if (images.length - 1 > imageIndex) {
                animate(imageView, images, imageIndex + 1,forever); //Calls itself until it gets to the end of the array
            }
            else {
                if (forever){
                animate(imageView, images, 0,forever);  //Calls itself to start the animation all over again in a loop if forever = true
                }
            }
        }
        public void onAnimationRepeat(Animation animation) {
            // TODO Auto-generated method stub
        }
        public void onAnimationStart(Animation animation) {
            // TODO Auto-generated method stub
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

  • @Crocodile你认为你的代码中可能存在内存问题.让具有上述代码的活动继续运行.它将创建如此多的AnimationSet对象.有一段时间后,它是否有可能与outOfMemory崩溃? (2认同)
  • @Gem - 为什么特定的分配会导致问题?每次调用imageView.setAnimation(动画)时,对前一个动画的任何引用都将丢失,因此垃圾收集器将能够删除此前一个对象.AFAIK,不是内存问题. (2认同)

Ald*_*ryd 64

要以您开始的方式实现此功能,您需要添加一个AnimationListener,以便您可以检测动画的开始和结束.当调用用于淡出的onAnimationEnd()时,可以将ImageView对象的可见性设置为View.INVISIBLE,切换图像并开始淡入淡出动画 - 这里也需要另一个AnimationListener.当您收到onAnimationEnd()用于淡入淡出动画时,将ImageView设置为View.VISIBLE,这样可以为您提供所需的效果.

我以前实现了类似的效果,但是我使用了带有2个ImageView而不是单个ImageView 的ViewSwitcher.您可以使用淡入和淡出为ViewSwitcher设置"in"和"out"动画,以便它可以管理AnimationListener实现.然后,您需要做的就是在2个ImageView之间切换.

编辑: 为了更有用,这里有一个如何使用ViewSwitcher的快速示例.我在https://github.com/aldryd/imageswitcher中包含了完整的源代码.

activity_main.xml中

    <ViewSwitcher
        android:id="@+id/switcher"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:inAnimation="@anim/fade_in"
        android:outAnimation="@anim/fade_out" >

        <ImageView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:scaleType="fitCenter"
            android:src="@drawable/sunset" />

        <ImageView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:scaleType="fitCenter"
            android:src="@drawable/clouds" />
    </ViewSwitcher>
Run Code Online (Sandbox Code Playgroud)

MainActivity.java

    // Let the ViewSwitcher do the animation listening for you
    ((ViewSwitcher) findViewById(R.id.switcher)).setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            ViewSwitcher switcher = (ViewSwitcher) v;

            if (switcher.getDisplayedChild() == 0) {
                switcher.showNext();
            } else {
                switcher.showPrevious();
            }
        }
    });
Run Code Online (Sandbox Code Playgroud)


mun*_*kay 44

您是否考虑过使用TransitionDrawable而不是自定义动画? https://developer.android.com/reference/android/graphics/drawable/TransitionDrawable.html

实现目标的一种方法是:

// create the transition layers
Drawable[] layers = new Drawable[2];
layers[0] = new BitmapDrawable(getResources(), firstBitmap);
layers[1] = new BitmapDrawable(getResources(), secondBitmap);

TransitionDrawable transitionDrawable = new TransitionDrawable(layers);
imageView.setImageDrawable(transitionDrawable);
transitionDrawable.startTransition(FADE_DURATION);
Run Code Online (Sandbox Code Playgroud)

  • 这是这个问题的最佳答案。 (2认同)

Raf*_*ael 6

我使用淡入淡出动画来替换旧图像的新图像

ObjectAnimator.ofFloat(imageView, View.ALPHA, 0.2f, 1.0f).setDuration(1000).start();
Run Code Online (Sandbox Code Playgroud)

  • 有关更清晰的代码,请参阅 http://android-developers.blogspot.com/2011/05/introducing-viewpropertyanimator.html。 (2认同)