/*
* Copyright (C) 2015 Jorge Castillo Pérez
*
* 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.github.jorgecastilloprz.completefab;
import android.animation.Animator;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.Interpolator;
import android.view.animation.LinearInterpolator;
import android.widget.FrameLayout;
import android.widget.ImageView;
import com.github.jorgecastilloprz.library.R;
/**
* This view represents the fake FAB that will be displayed at the end of the animation.
*
* @author Jorge Castillo Pérez
*/
public class CompleteFABView extends FrameLayout {
private final int RESET_DELAY = 3000;
private Drawable iconDrawable;
private int arcColor;
private CompleteFABListener listener;
private boolean viewsAdded;
public CompleteFABView(Context context, Drawable iconDrawable, int arcColor) {
super(context);
this.iconDrawable = iconDrawable;
this.arcColor = arcColor;
init();
}
public void attachListener(CompleteFABListener listener) {
this.listener = listener;
}
private void init() {
inflate(getContext(), R.layout.complete_fab, this);
}
private void tintCompleteFabWithArcColor() {
Drawable background = getResources().getDrawable(R.drawable.oval_complete);
background.setColorFilter(arcColor, PorterDuff.Mode.SRC_ATOP);
findViewById(R.id.completeFabRoot).setBackgroundDrawable(background);
}
private void setIcon() {
ImageView iconView = (ImageView) findViewById(R.id.completeFabIcon);
iconView.setImageDrawable(
iconDrawable != null ? iconDrawable : getResources().getDrawable(R.drawable.ic_done));
}
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if (!viewsAdded) {
setupContentSize();
tintCompleteFabWithArcColor();
setIcon();
viewsAdded = true;
}
}
private void setupContentSize() {
int contentSize = (int) getResources().getDimension(R.dimen.fab_content_size);
int mContentPadding = (getChildAt(0).getMeasuredWidth() - contentSize) / 2;
getChildAt(0).setPadding(mContentPadding, mContentPadding, mContentPadding, mContentPadding);
}
public void animate(AnimatorSet progressArcAnimator) {
animate(progressArcAnimator, false);
}
private void animate(AnimatorSet progressArcAnimator, boolean inverse) {
ValueAnimator completeFabAnim = ObjectAnimator.ofFloat(getChildAt(0), "alpha", inverse ? 0 : 1);
completeFabAnim.setDuration(300).setInterpolator(new AccelerateDecelerateInterpolator());
View icon = findViewById(R.id.completeFabIcon);
ValueAnimator iconScaleAnimX = ObjectAnimator.ofFloat(icon, "scaleX", 0, 1);
ValueAnimator iconScaleAnimY = ObjectAnimator.ofFloat(icon, "scaleY", 0, 1);
Interpolator iconAnimInterpolator = new LinearInterpolator();
iconScaleAnimX.setDuration(250).setInterpolator(iconAnimInterpolator);
iconScaleAnimY.setDuration(250).setInterpolator(iconAnimInterpolator);
AnimatorSet animatorSet = new AnimatorSet();
if (inverse) {
animatorSet.playTogether(completeFabAnim);
} else {
animatorSet.playTogether(completeFabAnim, progressArcAnimator, iconScaleAnimX,
iconScaleAnimY);
}
animatorSet.addListener(inverse ? getInverseAnimatorListener() : getAnimatorListener());
if (inverse) {
animatorSet.setStartDelay(RESET_DELAY);
}
animatorSet.start();
}
private Animator.AnimatorListener getAnimatorListener() {
return new Animator.AnimatorListener() {
@Override public void onAnimationStart(Animator animator) {
setVisibility(View.VISIBLE);
}
@Override public void onAnimationEnd(Animator animator) {
if (listener != null) {
listener.onCompleteFABAnimationEnd();
}
}
@Override public void onAnimationCancel(Animator animator) {
}
@Override public void onAnimationRepeat(Animator animator) {
}
};
}
private Animator.AnimatorListener getInverseAnimatorListener() {
return new Animator.AnimatorListener() {
@Override public void onAnimationStart(Animator animator) {
}
@Override public void onAnimationEnd(Animator animator) {
setVisibility(View.GONE);
}
@Override public void onAnimationCancel(Animator animator) {
}
@Override public void onAnimationRepeat(Animator animator) {
}
};
}
public void reset() {
animate(null, true);
}
/**
* This view must block every touch event so the user cannot click on fab anymore if this view
* is visible.
*/
@Override public boolean onTouchEvent(MotionEvent event) {
return true;
}
}