blob: 394fe580894fd1921c8a9806a7baa789f14083df [file] [log] [blame]
/*
* Copyright (C) 2016 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.android.incallui.answer.impl.hint;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.support.annotation.DimenRes;
import android.support.v4.view.animation.FastOutSlowInInterpolator;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Interpolator;
import android.view.animation.LinearInterpolator;
import android.widget.TextView;
/** An Answer hint that uses a green swiping dot. */
public class DotAnswerHint implements AnswerHint {
private static final float ANSWER_HINT_SMALL_ALPHA = 0.8f;
private static final float ANSWER_HINT_MID_ALPHA = 0.5f;
private static final float ANSWER_HINT_LARGE_ALPHA = 0.2f;
private static final long FADE_IN_DELAY_SCALE_MILLIS = 380;
private static final long FADE_IN_DURATION_SCALE_MILLIS = 200;
private static final long FADE_IN_DELAY_ALPHA_MILLIS = 340;
private static final long FADE_IN_DURATION_ALPHA_MILLIS = 50;
private static final long SWIPE_UP_DURATION_ALPHA_MILLIS = 500;
private static final long FADE_OUT_DELAY_SCALE_SMALL_MILLIS = 90;
private static final long FADE_OUT_DELAY_SCALE_MID_MILLIS = 70;
private static final long FADE_OUT_DELAY_SCALE_LARGE_MILLIS = 10;
private static final long FADE_OUT_DURATION_SCALE_MILLIS = 100;
private static final long FADE_OUT_DELAY_ALPHA_MILLIS = 130;
private static final long FADE_OUT_DURATION_ALPHA_MILLIS = 170;
private final Context context;
private final long puckUpDurationMillis;
private final long puckUpDelayMillis;
private View puck;
private View answerHintSmall;
private View answerHintMid;
private View answerHintLarge;
private View answerHintContainer;
private AnimatorSet answerGestureHintAnim;
public DotAnswerHint(Context context, long puckUpDurationMillis, long puckUpDelayMillis) {
this.context = context;
this.puckUpDurationMillis = puckUpDurationMillis;
this.puckUpDelayMillis = puckUpDelayMillis;
}
@Override
public void onCreateView(
LayoutInflater inflater, ViewGroup container, View puck, TextView hintText) {
this.puck = puck;
View view = inflater.inflate(R.layout.dot_hint, container, true);
answerHintContainer = view.findViewById(R.id.answer_hint_container);
answerHintSmall = view.findViewById(R.id.answer_hint_small);
answerHintMid = view.findViewById(R.id.answer_hint_mid);
answerHintLarge = view.findViewById(R.id.answer_hint_large);
hintText.setTextSize(
TypedValue.COMPLEX_UNIT_PX, context.getResources().getDimension(R.dimen.hint_text_size));
}
@Override
public void onBounceStart() {
if (answerGestureHintAnim == null) {
answerGestureHintAnim = new AnimatorSet();
answerHintContainer.setY(puck.getY() + getDimension(R.dimen.hint_initial_offset));
Animator fadeIn = createFadeIn();
Animator swipeUp =
ObjectAnimator.ofFloat(
answerHintContainer,
View.TRANSLATION_Y,
puck.getY() - getDimension(R.dimen.hint_offset));
swipeUp.setInterpolator(new FastOutSlowInInterpolator());
swipeUp.setDuration(SWIPE_UP_DURATION_ALPHA_MILLIS);
Animator fadeOut = createFadeOut();
answerGestureHintAnim.play(fadeIn).after(puckUpDelayMillis);
answerGestureHintAnim.play(swipeUp).after(fadeIn);
// The fade out should start fading the alpha just as the puck is dropping. Scaling will start
// a bit earlier.
answerGestureHintAnim
.play(fadeOut)
.after(puckUpDelayMillis + puckUpDurationMillis - FADE_OUT_DELAY_ALPHA_MILLIS);
fadeIn.addListener(
new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
super.onAnimationStart(animation);
answerHintSmall.setAlpha(0);
answerHintSmall.setScaleX(1);
answerHintSmall.setScaleY(1);
answerHintMid.setAlpha(0);
answerHintMid.setScaleX(1);
answerHintMid.setScaleY(1);
answerHintLarge.setAlpha(0);
answerHintLarge.setScaleX(1);
answerHintLarge.setScaleY(1);
answerHintContainer.setY(puck.getY() + getDimension(R.dimen.hint_initial_offset));
answerHintContainer.setVisibility(View.VISIBLE);
}
});
}
answerGestureHintAnim.start();
}
private Animator createFadeIn() {
AnimatorSet set = new AnimatorSet();
set.play(
createFadeInScaleAndAlpha(
answerHintSmall,
R.dimen.hint_small_begin_size,
R.dimen.hint_small_end_size,
ANSWER_HINT_SMALL_ALPHA))
.with(
createFadeInScaleAndAlpha(
answerHintMid,
R.dimen.hint_mid_begin_size,
R.dimen.hint_mid_end_size,
ANSWER_HINT_MID_ALPHA))
.with(
createFadeInScaleAndAlpha(
answerHintLarge,
R.dimen.hint_large_begin_size,
R.dimen.hint_large_end_size,
ANSWER_HINT_LARGE_ALPHA));
return set;
}
private Animator createFadeInScaleAndAlpha(
View target, @DimenRes int beginSize, @DimenRes int endSize, float endAlpha) {
Animator scale =
createUniformScaleAnimator(
target,
getDimension(beginSize),
getDimension(beginSize),
getDimension(endSize),
FADE_IN_DURATION_SCALE_MILLIS,
FADE_IN_DELAY_SCALE_MILLIS,
new LinearInterpolator());
Animator alpha =
createAlphaAnimator(
target,
0f,
endAlpha,
FADE_IN_DURATION_ALPHA_MILLIS,
FADE_IN_DELAY_ALPHA_MILLIS,
new LinearInterpolator());
AnimatorSet set = new AnimatorSet();
set.play(scale).with(alpha);
return set;
}
private Animator createFadeOut() {
AnimatorSet set = new AnimatorSet();
set.play(
createFadeOutScaleAndAlpha(
answerHintSmall,
R.dimen.hint_small_begin_size,
R.dimen.hint_small_end_size,
FADE_OUT_DELAY_SCALE_SMALL_MILLIS,
ANSWER_HINT_SMALL_ALPHA))
.with(
createFadeOutScaleAndAlpha(
answerHintMid,
R.dimen.hint_mid_begin_size,
R.dimen.hint_mid_end_size,
FADE_OUT_DELAY_SCALE_MID_MILLIS,
ANSWER_HINT_MID_ALPHA))
.with(
createFadeOutScaleAndAlpha(
answerHintLarge,
R.dimen.hint_large_begin_size,
R.dimen.hint_large_end_size,
FADE_OUT_DELAY_SCALE_LARGE_MILLIS,
ANSWER_HINT_LARGE_ALPHA));
return set;
}
private Animator createFadeOutScaleAndAlpha(
View target,
@DimenRes int beginSize,
@DimenRes int endSize,
long scaleDelay,
float endAlpha) {
Animator scale =
createUniformScaleAnimator(
target,
getDimension(beginSize),
getDimension(endSize),
getDimension(beginSize),
FADE_OUT_DURATION_SCALE_MILLIS,
scaleDelay,
new LinearInterpolator());
Animator alpha =
createAlphaAnimator(
target,
endAlpha,
0.0f,
FADE_OUT_DURATION_ALPHA_MILLIS,
FADE_OUT_DELAY_ALPHA_MILLIS,
new LinearInterpolator());
AnimatorSet set = new AnimatorSet();
set.play(scale).with(alpha);
return set;
}
@Override
public void onBounceEnd() {
if (answerGestureHintAnim != null) {
answerGestureHintAnim.end();
answerGestureHintAnim = null;
answerHintContainer.setVisibility(View.GONE);
}
}
@Override
public void onAnswered() {
AnswerHintFactory.increaseAnsweredCount(context);
}
private float getDimension(@DimenRes int id) {
return context.getResources().getDimension(id);
}
private static Animator createUniformScaleAnimator(
View target,
float original,
float begin,
float end,
long duration,
long delay,
Interpolator interpolator) {
float scaleBegin = begin / original;
float scaleEnd = end / original;
Animator scaleX = ObjectAnimator.ofFloat(target, View.SCALE_X, scaleBegin, scaleEnd);
Animator scaleY = ObjectAnimator.ofFloat(target, View.SCALE_Y, scaleBegin, scaleEnd);
scaleX.setDuration(duration);
scaleY.setDuration(duration);
scaleX.setInterpolator(interpolator);
scaleY.setInterpolator(interpolator);
AnimatorSet set = new AnimatorSet();
set.play(scaleX).with(scaleY).after(delay);
return set;
}
private static Animator createAlphaAnimator(
View target, float begin, float end, long duration, long delay, Interpolator interpolator) {
Animator alpha = ObjectAnimator.ofFloat(target, View.ALPHA, begin, end);
alpha.setDuration(duration);
alpha.setInterpolator(interpolator);
alpha.setStartDelay(delay);
return alpha;
}
}