【问题标题】:Creating animation on ImageView while changing image resource更改图像资源时在 ImageView 上创建动画
【发布时间】:2011-11-01 22:54:18
【问题描述】:

我的布局中只有一个ImageView,当检测到手势事件时,我正在更改其资源。我只想在更改 ImageView 的资源时显示动画。我可以将ViewFlipperone ImageView 一起使用吗?

【问题讨论】:

    标签: android


    【解决方案1】:

    对于单个图像视图,您可以使用此辅助函数:

    public static void ImageViewAnimatedChange(Context c, final ImageView v, final Bitmap new_image) {
        final Animation anim_out = AnimationUtils.loadAnimation(c, android.R.anim.fade_out); 
        final Animation anim_in  = AnimationUtils.loadAnimation(c, android.R.anim.fade_in); 
        anim_out.setAnimationListener(new AnimationListener()
        {
            @Override public void onAnimationStart(Animation animation) {}
            @Override public void onAnimationRepeat(Animation animation) {}
            @Override public void onAnimationEnd(Animation animation)
            {
                v.setImageBitmap(new_image); 
                anim_in.setAnimationListener(new AnimationListener() {
                    @Override public void onAnimationStart(Animation animation) {}
                    @Override public void onAnimationRepeat(Animation animation) {}
                    @Override public void onAnimationEnd(Animation animation) {}
                });
                v.startAnimation(anim_in);
            }
        });
        v.startAnimation(anim_out);
    }
    

    【讨论】:

    • 这其实是一个很好的答案,虽然动画不符合这个问题的需要。
    • 此代码有效,但在这种情况下无需设置 anim_in 侦听器。
    【解决方案2】:

    这是一个使用ImageSwitcher 的示例,就像@Konstantin Burov 建议的那样:

    将此ImageSwitcher 元素添加到您的 xml 布局中:

    <ImageSwitcher
       android:id="@+id/slide_trans_imageswitcher"
       android:layout_width="match_parent"
       android:layout_height="wrap_content">
    </ImageSwitcher>
    

    res/anim/中创建进出动画:

    出动画:

    //left_to_right_out.xml
    <?xml version="1.0" encoding="utf-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android"
         android:shareInterpolator="false">
        <translate android:fromXDelta="0%" android:toXDelta="100%"
                   android:fromYDelta="0%" android:toYDelta="0%"
                   android:duration="700"/>
    </set>
    

    在动画中:

    //left_to_right_in.xml
    <?xml version="1.0" encoding="utf-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android"
         android:shareInterpolator="false">
        <translate android:fromXDelta="-100%" android:toXDelta="0%"
                   android:fromYDelta="0%" android:toYDelta="0%"
                   android:duration="700"/>
    </set>
    

    在您的代码中初始化它们:

            Animation in  = AnimationUtils.loadAnimation(this, R.anim.left_to_right_in);
            Animation out = AnimationUtils.loadAnimation(this, R.anim.left_to_right_out);
    

    初始化你的ImageSwitcher:

    private ImageSwitcher imageSwitcher;
    imageSwitcher = (ImageSwitcher)findViewById(R.id.slide_trans_imageswitcher);
    

    给它附加动画:

    imageSwitcher.setInAnimation(in);
    imageSwitcher.setOutAnimation(out);
    

    现在每次为imageSwitcher设置图片资源时,都会切换成幻灯片动画。


    例如,我们可以每 X 秒更换一次图像:

    private int animationCounter = 1;
    private Handler imageSwitcherHandler;
    imageSwitcherHandler = new Handler(Looper.getMainLooper());
    imageSwitcherHandler.post(new Runnable() {
        @Override
        public void run() {
            switch (animationCounter++) {
                case 1:
                    imageSwitcher.setImageResource(R.drawable.image1);
                    break;
                case 2:
                    imageSwitcher.setImageResource(R.drawable.image2);
                    break;
                case 3:
                    imageSwitcher.setImageResource(R.drawable.image3);
                    break;
            }
            animationCounter %= 4;
            if(animationCounter == 0 ) animationCounter = 1;
    
            imageSwitcherHandler.postDelayed(this, 3000);
        }
    });
    

    【讨论】:

    • 不支持向量
    • 你还需要定义 ImageView 工厂,否则你会在没有 stacttrace 的情况下发生严重的崩溃。 is.setFactory( () -&gt; { new ImageView(this) } );
    【解决方案3】:

    我找到了另一种使用过渡 drawable 为其设置动画的方法(我从 here 获得了想法)

    public static void setImageDrawableWithAnimation(ImageView imageView,
                                                     Drawable drawable,
                                                     int duration) {
        Drawable currentDrawable = imageView.getDrawable();
        if (currentDrawable == null) {
            imageView.setImageDrawable(drawable);
            return;
        }
    
        TransitionDrawable transitionDrawable = new TransitionDrawable(new Drawable[] {
                currentDrawable,
                drawable
        });
        imageView.setImageDrawable(transitionDrawable);
        transitionDrawable.startTransition(duration);
    }
    

    类比kotlin扩展函数:

    fun ImageView.setImageDrawableWithAnimation(drawable: Drawable, duration: Int = 300) {
        val currentDrawable = getDrawable()
        if (currentDrawable == null) {
            setImageDrawable(drawable)
            return
        }
    
        val transitionDrawable = TransitionDrawable(arrayOf(
                currentDrawable,
                drawable
        ))
        setImageDrawable(transitionDrawable)
        transitionDrawable.startTransition(duration)
    }
    

    如果你的drawables包含透明部分,这个标志可能有助于防止旧的drawable可见性:

    transitionDrawable.setCrossFadeEnabled(true);
    

    【讨论】:

      【解决方案4】:

      考虑使用 API 演示应用中提供的 Rotate3dAnimation。 视图 > 动画 > 3D 过渡

      你也可以check this关于SO的问题

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-05-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-06-21
        • 1970-01-01
        • 1970-01-01
        • 2013-12-21
        相关资源
        最近更新 更多