summaryrefslogtreecommitdiff
path: root/java/com/android/incallui/answer/impl/hint/DotAnswerHint.java
diff options
context:
space:
mode:
Diffstat (limited to 'java/com/android/incallui/answer/impl/hint/DotAnswerHint.java')
-rw-r--r--java/com/android/incallui/answer/impl/hint/DotAnswerHint.java283
1 files changed, 283 insertions, 0 deletions
diff --git a/java/com/android/incallui/answer/impl/hint/DotAnswerHint.java b/java/com/android/incallui/answer/impl/hint/DotAnswerHint.java
new file mode 100644
index 000000000..394fe5808
--- /dev/null
+++ b/java/com/android/incallui/answer/impl/hint/DotAnswerHint.java
@@ -0,0 +1,283 @@
+/*
+ * 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;
+ }
+}