Home | History | Annotate | Download | only in ui
      1 /*
      2  * Copyright (C) 2013 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.camera.ui;
     18 
     19 import android.animation.Animator;
     20 import android.animation.AnimatorSet;
     21 import android.animation.ValueAnimator;
     22 import android.content.Context;
     23 import android.graphics.Canvas;
     24 import android.graphics.Color;
     25 import android.graphics.Paint;
     26 import android.graphics.RectF;
     27 import android.util.AttributeSet;
     28 import android.view.View;
     29 import android.view.animation.Interpolator;
     30 import android.view.animation.LinearInterpolator;
     31 
     32 import com.android.camera.debug.Log;
     33 
     34 /**
     35  * This class handles all the animations at capture time. Post capture animations
     36  * will be handled in a separate place.
     37  */
     38 public class CaptureAnimationOverlay extends View
     39         implements PreviewStatusListener.PreviewAreaChangedListener {
     40     private final static Log.Tag TAG = new Log.Tag("CaptureAnimOverlay");
     41 
     42     private final static int FLASH_COLOR = Color.WHITE;
     43 
     44     private static final float FLASH_MAX_ALPHA = 0.85f;
     45     private static final long FLASH_FULL_DURATION_MS = 65;
     46     private static final long FLASH_DECREASE_DURATION_MS = 150;
     47     private static final float SHORT_FLASH_MAX_ALPHA = 0.75f;
     48     private static final long SHORT_FLASH_FULL_DURATION_MS = 34;
     49     private static final long SHORT_FLASH_DECREASE_DURATION_MS = 100;
     50 
     51     private AnimatorSet mFlashAnimation;
     52     private final RectF mPreviewArea = new RectF();
     53     private final Paint mPaint = new Paint();
     54     private final Interpolator mFlashAnimInterpolator;
     55     private final ValueAnimator.AnimatorUpdateListener mFlashAnimUpdateListener;
     56     private final Animator.AnimatorListener mFlashAnimListener;
     57 
     58     public CaptureAnimationOverlay(Context context, AttributeSet attrs) {
     59         super(context, attrs);
     60         mPaint.setColor(FLASH_COLOR);
     61         mFlashAnimInterpolator = new LinearInterpolator();
     62         mFlashAnimUpdateListener = new ValueAnimator.AnimatorUpdateListener() {
     63             @Override
     64             public void onAnimationUpdate(ValueAnimator animation) {
     65                 float alpha = 255.0f * (Float) animation.getAnimatedValue();
     66                 mPaint.setAlpha((int) alpha);
     67                 invalidate();
     68             }
     69         };
     70         mFlashAnimListener = new Animator.AnimatorListener() {
     71             @Override
     72             public void onAnimationStart(Animator animation) {
     73                 setVisibility(VISIBLE);
     74             }
     75 
     76             @Override
     77             public void onAnimationEnd(Animator animation) {
     78                 mFlashAnimation = null;
     79                 setVisibility(INVISIBLE);
     80             }
     81 
     82             @Override
     83             public void onAnimationCancel(Animator animation) {
     84                 // End is always called after cancel.
     85             }
     86 
     87             @Override
     88             public void onAnimationRepeat(Animator animation) {
     89 
     90             }
     91         };
     92     }
     93 
     94     /**
     95      * Start flash animation.
     96      *
     97      * @param shortFlash show shortest possible flash instead of regular long version.
     98      */
     99     public void startFlashAnimation(boolean shortFlash) {
    100         if (mFlashAnimation != null && mFlashAnimation.isRunning()) {
    101             mFlashAnimation.cancel();
    102         }
    103         float maxAlpha;
    104 
    105         if (shortFlash) {
    106             maxAlpha = SHORT_FLASH_MAX_ALPHA;
    107         } else {
    108             maxAlpha = FLASH_MAX_ALPHA;
    109         }
    110 
    111         ValueAnimator flashAnim1 = ValueAnimator.ofFloat(maxAlpha, maxAlpha);
    112         ValueAnimator flashAnim2 = ValueAnimator.ofFloat(maxAlpha, .0f);
    113 
    114         if (shortFlash) {
    115             flashAnim1.setDuration(SHORT_FLASH_FULL_DURATION_MS);
    116             flashAnim2.setDuration(SHORT_FLASH_DECREASE_DURATION_MS);
    117         } else {
    118             flashAnim1.setDuration(FLASH_FULL_DURATION_MS);
    119             flashAnim2.setDuration(FLASH_DECREASE_DURATION_MS);
    120         }
    121 
    122         flashAnim1.addUpdateListener(mFlashAnimUpdateListener);
    123         flashAnim2.addUpdateListener(mFlashAnimUpdateListener);
    124         flashAnim1.setInterpolator(mFlashAnimInterpolator);
    125         flashAnim2.setInterpolator(mFlashAnimInterpolator);
    126 
    127         mFlashAnimation = new AnimatorSet();
    128         mFlashAnimation.play(flashAnim1).before(flashAnim2);
    129         mFlashAnimation.addListener(mFlashAnimListener);
    130         mFlashAnimation.start();
    131     }
    132 
    133     @Override
    134     public void onPreviewAreaChanged(RectF previewArea) {
    135         mPreviewArea.set(previewArea);
    136     }
    137 
    138     @Override
    139     public void onDraw(Canvas canvas) {
    140         if (mFlashAnimation != null && mFlashAnimation.isRunning()) {
    141             // mPaint alpha is animated by the animation.
    142             canvas.drawRect(mPreviewArea, mPaint);
    143             canvas.clipRect(mPreviewArea);
    144         }
    145     }
    146 
    147     @Override
    148     public boolean hasOverlappingRendering() {
    149         // The internal draw method will NOT have draw calls that overlap.
    150         return false;
    151     }
    152 }
    153