Home | History | Annotate | Download | only in widget
      1 /*
      2  * Copyright (C) 2016 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.example.android.support.transition.widget;
     18 
     19 import android.animation.Animator;
     20 import android.animation.ArgbEvaluator;
     21 import android.animation.ValueAnimator;
     22 import android.graphics.drawable.ColorDrawable;
     23 import android.graphics.drawable.Drawable;
     24 import android.support.annotation.NonNull;
     25 import android.support.annotation.Nullable;
     26 import android.support.transition.Transition;
     27 import android.support.transition.TransitionValues;
     28 import android.view.View;
     29 import android.view.ViewGroup;
     30 
     31 /**
     32  * A sample implementation of support {@link Transition}.
     33  */
     34 public class ChangeColor extends Transition {
     35 
     36     /** Key to store a color value in TransitionValues object */
     37     private static final String PROPNAME_BACKGROUND = "transitiondemos:change_color:background";
     38 
     39     /**
     40      * Convenience method: Add the background Drawable property value
     41      * to the TransitionsValues.value Map for a target.
     42      */
     43     private void captureValues(TransitionValues values) {
     44         // Capture the property values of views for later use
     45         values.values.put(PROPNAME_BACKGROUND, values.view.getBackground());
     46     }
     47 
     48     @Override
     49     public void captureEndValues(@NonNull TransitionValues transitionValues) {
     50         captureValues(transitionValues);
     51     }
     52 
     53     @Override
     54     public void captureStartValues(@NonNull TransitionValues transitionValues) {
     55         captureValues(transitionValues);
     56     }
     57 
     58     // Create an animation for each target that is in both the starting and ending Scene. For each
     59     // pair of targets, if their background property value is a color (rather than a graphic),
     60     // create a ValueAnimator based on an ArgbEvaluator that interpolates between the starting and
     61     // ending color. Also create an update listener that sets the View background color for each
     62     // animation frame
     63     @Nullable
     64     @Override
     65     public Animator createAnimator(@NonNull ViewGroup sceneRoot,
     66                                    @Nullable TransitionValues startValues,
     67                                    @Nullable TransitionValues endValues) {
     68         // This transition can only be applied to views that are on both starting and ending scenes.
     69         if (null == startValues || null == endValues) {
     70             return null;
     71         }
     72         // Store a convenient reference to the target. Both the starting and ending layout have the
     73         // same target.
     74         final View view = endValues.view;
     75         // Store the object containing the background property for both the starting and ending
     76         // layouts.
     77         Drawable startBackground = (Drawable) startValues.values.get(PROPNAME_BACKGROUND);
     78         Drawable endBackground = (Drawable) endValues.values.get(PROPNAME_BACKGROUND);
     79         // This transition changes background colors for a target. It doesn't animate any other
     80         // background changes. If the property isn't a ColorDrawable, ignore the target.
     81         if (startBackground instanceof ColorDrawable && endBackground instanceof ColorDrawable) {
     82             ColorDrawable startColor = (ColorDrawable) startBackground;
     83             ColorDrawable endColor = (ColorDrawable) endBackground;
     84             // If the background color for the target in the starting and ending layouts is
     85             // different, create an animation.
     86             if (startColor.getColor() != endColor.getColor()) {
     87                 // Create a new Animator object to apply to the targets as the transitions framework
     88                 // changes from the starting to the ending layout. Use the class ValueAnimator,
     89                 // which provides a timing pulse to change property values provided to it. The
     90                 // animation runs on the UI thread. The Evaluator controls what type of
     91                 // interpolation is done. In this case, an ArgbEvaluator interpolates between two
     92                 // #argb values, which are specified as the 2nd and 3rd input arguments.
     93                 ValueAnimator animator = ValueAnimator.ofObject(new ArgbEvaluator(),
     94                         startColor.getColor(), endColor.getColor());
     95                 // Add an update listener to the Animator object.
     96                 animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
     97                     @Override
     98                     public void onAnimationUpdate(ValueAnimator animation) {
     99                         Object value = animation.getAnimatedValue();
    100                         // Each time the ValueAnimator produces a new frame in the animation, change
    101                         // the background color of the target. Ensure that the value isn't null.
    102                         if (null != value) {
    103                             view.setBackgroundColor((Integer) value);
    104                         }
    105                     }
    106                 });
    107                 // Return the Animator object to the transitions framework. As the framework changes
    108                 // between the starting and ending layouts, it applies the animation you've created.
    109                 return animator;
    110             }
    111         }
    112         // For non-ColorDrawable backgrounds, we just return null, and no animation will take place.
    113         return null;
    114     }
    115 
    116 }
    117