Home | History | Annotate | Download | only in deskclock
      1 /*
      2  * Copyright (C) 2015 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.deskclock;
     18 
     19 import android.animation.Animator;
     20 import android.animation.AnimatorListenerAdapter;
     21 import android.animation.ValueAnimator;
     22 import android.animation.ValueAnimator.AnimatorUpdateListener;
     23 import android.graphics.drawable.ColorDrawable;
     24 import android.os.Bundle;
     25 import android.support.annotation.ColorInt;
     26 import android.support.v7.app.AppCompatActivity;
     27 import android.view.View;
     28 
     29 import static com.android.deskclock.AnimatorUtils.ARGB_EVALUATOR;
     30 
     31 /**
     32  * Base activity class that changes the app window's color based on the current hour.
     33  */
     34 public abstract class BaseActivity extends AppCompatActivity {
     35 
     36     /** Sets the app window color on each frame of the {@link #mAppColorAnimator}. */
     37     private final AppColorAnimationListener mAppColorAnimationListener
     38             = new AppColorAnimationListener();
     39 
     40     /** The current animator that is changing the app window color or {@code null}. */
     41     private ValueAnimator mAppColorAnimator;
     42 
     43     /** Draws the app window's color. */
     44     private ColorDrawable mBackground;
     45 
     46     @Override
     47     protected void onCreate(Bundle savedInstanceState) {
     48         super.onCreate(savedInstanceState);
     49 
     50         // Allow the content to layout behind the status and navigation bars.
     51         getWindow().getDecorView().setSystemUiVisibility(
     52                 View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
     53                         | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
     54                         | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
     55 
     56         final @ColorInt int color = ThemeUtils.resolveColor(this, android.R.attr.windowBackground);
     57         adjustAppColor(color, false /* animate */);
     58     }
     59 
     60     @Override
     61     protected void onStart() {
     62         super.onStart();
     63 
     64         // Ensure the app window color is up-to-date.
     65         final @ColorInt int color = ThemeUtils.resolveColor(this, android.R.attr.windowBackground);
     66         adjustAppColor(color, false /* animate */);
     67     }
     68 
     69     /**
     70      * Adjusts the current app window color of this activity; animates the change if desired.
     71      *
     72      * @param color   the ARGB value to set as the current app window color
     73      * @param animate {@code true} if the change should be animated
     74      */
     75     protected void adjustAppColor(@ColorInt int color, boolean animate) {
     76         // Create and install the drawable that defines the window color.
     77         if (mBackground == null) {
     78             mBackground = new ColorDrawable(color);
     79             getWindow().setBackgroundDrawable(mBackground);
     80         }
     81 
     82         // Cancel the current window color animation if one exists.
     83         if (mAppColorAnimator != null) {
     84             mAppColorAnimator.cancel();
     85         }
     86 
     87         final @ColorInt int currentColor = mBackground.getColor();
     88         if (currentColor != color) {
     89             if (animate) {
     90                 mAppColorAnimator = ValueAnimator.ofObject(ARGB_EVALUATOR, currentColor, color)
     91                         .setDuration(3000L);
     92                 mAppColorAnimator.addUpdateListener(mAppColorAnimationListener);
     93                 mAppColorAnimator.addListener(mAppColorAnimationListener);
     94                 mAppColorAnimator.start();
     95             } else {
     96                 setAppColor(color);
     97             }
     98         }
     99     }
    100 
    101     private void setAppColor(@ColorInt int color) {
    102         mBackground.setColor(color);
    103     }
    104 
    105     /**
    106      * Sets the app window color to the current color produced by the animator.
    107      */
    108     private final class AppColorAnimationListener extends AnimatorListenerAdapter
    109             implements AnimatorUpdateListener {
    110         @Override
    111         public void onAnimationUpdate(ValueAnimator valueAnimator) {
    112             final @ColorInt int color = (int) valueAnimator.getAnimatedValue();
    113             setAppColor(color);
    114         }
    115 
    116         @Override
    117         public void onAnimationEnd(Animator animation) {
    118             if (mAppColorAnimator == animation) {
    119                 mAppColorAnimator = null;
    120             }
    121         }
    122     }
    123 }
    124