首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >有没有办法监听动画在AnimatedVectorDrawables中结束?

有没有办法监听动画在AnimatedVectorDrawables中结束?
EN

Stack Overflow用户
提问于 2015-03-02 22:47:50
回答 3查看 7K关注 0票数 22

我已经创建了一个AnimatedVectorDrawable,它工作得很好,现在我正在寻找一种方法来更改动画或隐藏视图后,它完成。我希望有一个听众,但看起来好像没有。有人能帮帮忙吗?

编辑

所以我找到了一个变通方法,但不是一个非常优雅的方法。我所做的是创建一个线程并轮询动画是否正在运行。

代码语言:javascript
复制
new Runnable() {
    public void run() {
        while(mLoop) {
            if(mAnimatedVectorDrawable.isRunning()) {
                Thread.sleep(mPollingInterval);
            } else {
                mLoop = false;
                // TODO what ever
            }
        }
    }
};

如果有人找到了更好的解决方案,请分享。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-03-07 10:19:48

我的第一反应是获取源代码,添加一些回调,并在其中创建一个自定义的可绘制。当然,这将意味着不支持xml。

事实证明,AnimatedVectorDrawable使用的是VectorDrawable's私有方法。所以,这种方法是行不通的。

我们可以围绕AnimatedVectorDrawable创建一个简单的包装类,并添加回调:

代码语言:javascript
复制
public class AVDWrapper {

    private Handler mHandler;
    private Animatable mDrawable;
    private Callback mCallback;
    private Runnable mAnimationDoneRunnable = new Runnable() {

        @Override
        public void run() {
            if (mCallback != null)
                mCallback.onAnimationDone();
        }
    };

    public interface Callback {
        public void onAnimationDone();
        public void onAnimationStopped();
    }

    public AVDWrapper(Animatable drawable, 
                            Handler handler, Callback callback) {
        mDrawable = drawable;
        mHandler = handler;
        mCallback = callback;
    }

    // Duration of the animation
    public void start(long duration) {
        mDrawable.start();
        mHandler.postDelayed(mAnimationDoneRunnable, duration);
    }

    public void stop() {
        mDrawable.stop();
        mHandler.removeCallbacks(mAnimationDoneRunnable);

        if (mCallback != null)
            mCallback.onAnimationStopped();
    }
}

您的代码将如下所示:

代码语言:javascript
复制
final Drawable drawable = circle.getDrawable();
final Animatable animatable = (Animatable) drawable;

AVDWrapper.Callback callback = new AVDWrapper.Callback() {
        @Override
        public void onAnimationDone() {
            tick.setAlpha(1f);
        }

        @Override
        public void onAnimationStopped() {
          // Okay
        }
    };

AVDWrapper avdw = new AVDWrapper(animatable, mHandler, callback);
//animatable.start();
avdw.start(2000L);

tick.setAlpha(0f);
//tick.animate().alpha(1f).setStartDelay(2000).setDuration(1).start();

// One wrapper is sufficient if the duration is same
final Drawable drawable2 = tick.getDrawable();
final Animatable animatable2 = (Animatable) drawable2;
animatable2.start();

但是,这正是您对setStartDelay所做的事情。所以我不知道这会有多大用处。

编辑:所有这些也可以在扩展的AnimatedVectorDrawable中实现。但是,您将完全失去对xml的支持。

票数 8
EN

Stack Overflow用户

发布于 2015-03-13 02:47:03

奇怪的是,没有直接的API来获取它。我想一个不涉及覆盖的变通方法只是简单地在你的动画集中找到花费最多时间的动画,然后发布一个延迟的runnable来隐藏视图。

代码语言:javascript
复制
int longestAnimationTime = 500; //miliseconds, defined in XML possibly?
drawable.start();
drawableView.postDelayed(new Runnable() {

        @Override
        public void run() {
            drawableView.setVisibility(View.GONE);
        }
}, longestAnimationTime);

缺点是它涉及到硬编码最长的动画时间,但只要在动画XML和代码中引用相同的常量值,它就会正常工作,不需要重写。

票数 4
EN

Stack Overflow用户

发布于 2015-03-07 05:15:35

我发现了同样的问题。我正在尝试动画画一个圆和里面的一个刻度。

我能做的最好的事情就是玩玩持续时间。如下所示:

代码语言:javascript
复制
final Drawable drawable = circle.getDrawable();
final Animatable animatable = (Animatable) drawable;
animatable.start();

tick.setAlpha(0f);
tick.animate().alpha(1f).setStartDelay(2000).setDuration(1).start();
final Drawable drawable2 = tick.getDrawable();
final Animatable animatable2 = (Animatable) drawable2;
animatable2.start();

如果有一个倾听者那就太好了

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28812604

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档