/*
* Copyright 2016 Hippo Seven
*
* 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.hippo.reveal;
import android.animation.Animator;
import android.animation.ValueAnimator;
import android.annotation.TargetApi;
import android.os.Build;
import android.view.View;
import com.hippo.yorozuya.SimpleAnimatorListener;
public final class ViewAnimationUtils {
private ViewAnimationUtils() {}
public static final boolean API_SUPPORT_CIRCULAR_REVEAL =
Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP;
// http://developer.android.com/guide/topics/graphics/hardware-accel.html#unsupported
public static final boolean API_SUPPORT_CANVAS_CLIP_PATH =
Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2;
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public static Animator createCircularReveal(View view,
int centerX, int centerY, float startRadius, float endRadius) {
if (API_SUPPORT_CIRCULAR_REVEAL) {
return android.view.ViewAnimationUtils.createCircularReveal(
view, centerX, centerY, startRadius, endRadius);
} else if (view instanceof Reveal){
return createRevealAnimator((Reveal) view, centerX, centerY,
startRadius, endRadius);
} else {
throw new IllegalStateException("Only View implements CircularReveal or" +
" api >= 21 can create circular reveal");
}
}
private static Animator createRevealAnimator(Reveal reveal, int centerX, int centerY,
float startRadius, float endRadius) {
ValueAnimator animator = ValueAnimator.ofFloat(startRadius, endRadius);
animator.addUpdateListener(new RevealAnimatorUpdateListener(reveal, centerX, centerY));
animator.addListener(new RevealAnimatorListener(reveal));
return animator;
}
private static class RevealAnimatorUpdateListener
implements ValueAnimator.AnimatorUpdateListener {
private final Reveal mReveal;
private final int mCenterX;
private final int mCenterY;
public RevealAnimatorUpdateListener(Reveal reveal, int centerX, int centerY) {
mReveal = reveal;
mCenterX = centerX;
mCenterY = centerY;
}
@Override
public void onAnimationUpdate(ValueAnimator animation) {
Object value = animation.getAnimatedValue();
if (value instanceof Float) {
mReveal.setReveal(mCenterX, mCenterY, (Float) value);
}
}
}
private static class RevealAnimatorListener extends SimpleAnimatorListener {
private final Reveal mReveal;
private final View mView;
public RevealAnimatorListener(Reveal reveal) {
mReveal = reveal;
mView = (View) reveal;
}
@Override
public void onAnimationStart(Animator animation) {
if (!API_SUPPORT_CANVAS_CLIP_PATH) {
mView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}
mReveal.setRevealEnable(true);
}
@Override
public void onAnimationEnd(Animator animation) {
mReveal.setRevealEnable(false);
if (!API_SUPPORT_CANVAS_CLIP_PATH) {
mView.setLayerType(View.LAYER_TYPE_NONE, null);
}
}
}
}