/*
* Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hannesdorfmann.mosby3.sample.mail.ui.transition;
import android.animation.Animator;
import android.animation.TimeInterpolator;
import android.annotation.TargetApi;
import android.content.Context;
import android.transition.TransitionValues;
import android.transition.Visibility;
import android.util.ArrayMap;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewAnimationUtils;
import android.view.ViewGroup;
import java.util.ArrayList;
@TargetApi(21)
public class RevealVisibilityTransition extends Visibility {
public RevealVisibilityTransition() {
}
public RevealVisibilityTransition(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public Animator onAppear(ViewGroup sceneRoot, final View view, TransitionValues startValues,
TransitionValues endValues) {
Animator reveal = ViewAnimationUtils.createCircularReveal(view, 140, 200,
0, 1000);
return new NoPauseAnimator(reveal);
}
@Override
public Animator onDisappear(ViewGroup sceneRoot, View view, TransitionValues startValues,
TransitionValues endValues) {
Animator reveal = ViewAnimationUtils.createCircularReveal(view, 140, 200,
1000, 0);
return new NoPauseAnimator(reveal);
}
private Animator createAnimator(View view, float startRadius, float endRadius) {
int centerX = view.getWidth() / 2;
int centerY = view.getHeight() / 2;
Animator reveal = ViewAnimationUtils.createCircularReveal(view, centerX, centerY,
startRadius, endRadius);
return new NoPauseAnimator(reveal);
}
static double calculateMaxRadius(View view) {
double widthSquared = view.getWidth() * view.getWidth();
double heightSquared = view.getHeight() * view.getHeight();
double radius = Math.sqrt(widthSquared + heightSquared) / 2;
return radius;
}
private static class NoPauseAnimator extends Animator {
private final Animator mAnimator;
private final ArrayMap<AnimatorListener, AnimatorListener> mListeners =
new ArrayMap<AnimatorListener, AnimatorListener>();
public NoPauseAnimator(Animator animator) {
mAnimator = animator;
}
@Override
public void addListener(AnimatorListener listener) {
AnimatorListener wrapper = new AnimatorListenerWrapper(this, listener);
if (!mListeners.containsKey(listener)) {
mListeners.put(listener, wrapper);
mAnimator.addListener(wrapper);
}
}
@Override
public void cancel() {
mAnimator.cancel();
}
@Override
public void end() {
mAnimator.end();
}
@Override
public long getDuration() {
return mAnimator.getDuration();
}
@Override
public TimeInterpolator getInterpolator() {
return mAnimator.getInterpolator();
}
@Override
public ArrayList<AnimatorListener> getListeners() {
return new ArrayList<AnimatorListener>(mListeners.keySet());
}
@Override
public long getStartDelay() {
return mAnimator.getStartDelay();
}
@Override
public boolean isPaused() {
return mAnimator.isPaused();
}
@Override
public boolean isRunning() {
return mAnimator.isRunning();
}
@Override
public boolean isStarted() {
return mAnimator.isStarted();
}
@Override
public void removeAllListeners() {
mListeners.clear();
mAnimator.removeAllListeners();
}
@Override
public void removeListener(AnimatorListener listener) {
AnimatorListener wrapper = mListeners.get(listener);
if (wrapper != null) {
mListeners.remove(listener);
mAnimator.removeListener(wrapper);
}
}
/* We don't want to override pause or resume methods because we don't want them
* to affect mAnimator.
public void pause();
public void resume();
public void addPauseListener(AnimatorPauseListener listener);
public void removePauseListener(AnimatorPauseListener listener);
*/
@Override
public Animator setDuration(long durationMS) {
mAnimator.setDuration(durationMS);
return this;
}
@Override
public void setInterpolator(TimeInterpolator timeInterpolator) {
mAnimator.setInterpolator(timeInterpolator);
}
@Override
public void setStartDelay(long delayMS) {
mAnimator.setStartDelay(delayMS);
}
@Override
public void setTarget(Object target) {
mAnimator.setTarget(target);
}
@Override
public void setupEndValues() {
mAnimator.setupEndValues();
}
@Override
public void setupStartValues() {
mAnimator.setupStartValues();
}
@Override
public void start() {
mAnimator.start();
}
}
private static class AnimatorListenerWrapper implements Animator.AnimatorListener {
private final Animator mAnimator;
private final Animator.AnimatorListener mListener;
public AnimatorListenerWrapper(Animator animator, Animator.AnimatorListener listener) {
mAnimator = animator;
mListener = listener;
}
@Override
public void onAnimationStart(Animator animator) {
mListener.onAnimationStart(mAnimator);
}
@Override
public void onAnimationEnd(Animator animator) {
mListener.onAnimationEnd(mAnimator);
}
@Override
public void onAnimationCancel(Animator animator) {
mListener.onAnimationCancel(mAnimator);
}
@Override
public void onAnimationRepeat(Animator animator) {
mListener.onAnimationRepeat(mAnimator);
}
}
}