在这个动画监听器中进行回调的最佳方法是什么?

时间:2015-01-12 05:02:50

标签: java android android-animation

在很多地方,我发现自己的内容正在逐渐消失。

我决定创建一个名为Fade的帮手。

Fade虽然有一个有问题的方法:

public class Fade {

    public static void hide(final View view, AnimatorListenerAdapter listener) {
        if (view.getVisibility() == View.VISIBLE) {
            view.animate().setDuration(DURATION);
            view.animate().alpha(0f).setListener(listener);
        }
    }

}

为了让Fade.hide按照需要运行,我需要AnimationListenerAdapter在其onAnimationEnd方法中执行以下操作。请注意,我之所以不这样做是因为使用此助手的人应该能够在淡入淡出开始,结束等时自定义侦听器。

view.setAlpha(1f);
view.setVisibility(View.INVISIBLE);
view.animate().setListener(null);

其中view引用在此帮助程序的客户端上使用的View。

我认为这种行为是非常不受欢迎的,并且让我怀疑是否值得拥有助手。

我不能让使用帮助器的人在AnimatorListenerAdapter中传递,然后我以某种方式填充到我自己的AnimatorListenerAdapter中。

我想要做以下事情,但绝对是hacky:

public static void hide(final View view, Runnable endAction) {
    if (view.getVisibility() == View.VISIBLE) {
        view.animate().setDuration(DURATION);
        view.animate().alpha(0f).setListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
                view.setAlpha(1f);
                view.setVisibility(View.INVISIBLE);
                view.animate().setListener(null);

                endAction.run();
           }
        }
    }
}

这似乎非常hacky,最终需要我制作许多方法签名来解释所有AnimatorListenerAdapter回调,如onAnimationRepeat,onAnimationStart等。

有没有减轻这种情况,或者我应该减少代码气味,只是在任何类别中创建相同的方法做很多褪色?

1 个答案:

答案 0 :(得分:2)

您可以做的是使用一个合成AnimatorListenerAdapter来包装提供的侦听器,并在完成所需的工作后委派调用。例如:

public final class FadeHelper {
    public static void fade(final View view, Animator.AnimatorListener listener) {
        if (view.getVisibility() == View.VISIBLE) {

            // Create a composite listener and override onAnimationEnd()
            // to do your own thing, then call through to super to pass
            // the event to the provided listener.
            final Animator.AnimatorListener compositeListener = new CompositeAnimatorListenerAdapter(listener) {
                @Override
                public void onAnimationEnd(Animator animator) {
                    view.setAlpha(1f);
                    view.setVisibility(View.INVISIBLE);

                    // Not sure why this line is necessary?
                    view.animate().setListener(null);

                    // This passes the event to the original listener
                    super.onAnimationEnd(animator);
                }
            });

            view.animate()
                .setDuration(DURATION)
                .alpha(0f)
                .setListener(compositeListener);
        }
    }

    private static class CompositeAnimatorListenerAdapter implements Animator.AnimatorListener {
        private final Animator.AnimatorListener mDelegate;

        public CompositeAnimatorListenerAdapter(Animator.AnimatorListener delegate) {
            mDelegate = delegate;
        }

        @Override
        public void onAnimationStart(Animator animator) {
            if (mDelegate != null) {
                mDelegate.onAnimationStart(animator);
            }
        }

        @Override
        public void onAnimationEnd(Animator animator) {
            if (mDelegate != null) {
                mDelegate.onAnimationEnd(animator);
            }
        }

        @Override
        public void onAnimationCancel(Animator animator) {
            if (mDelegate != null) {
                mDelegate.onAnimationCancel(animator);
            }
        }

        @Override
        public void onAnimationRepeat(Animator animator) {
            if (mDelegate != null) {
                mDelegate.onAnimationRepeat(animator);
            }
        }
    }
}