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 androidx.annotation.ColorInt; 26 import androidx.appcompat.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 onCreate(Bundle savedInstanceState)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 onStart()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 */ adjustAppColor(@olorInt int color, boolean animate)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 setAppColor(@olorInt int color)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 onAnimationUpdate(ValueAnimator valueAnimator)111 public void onAnimationUpdate(ValueAnimator valueAnimator) { 112 final @ColorInt int color = (int) valueAnimator.getAnimatedValue(); 113 setAppColor(color); 114 } 115 116 @Override onAnimationEnd(Animator animation)117 public void onAnimationEnd(Animator animation) { 118 if (mAppColorAnimator == animation) { 119 mAppColorAnimator = null; 120 } 121 } 122 } 123 } 124