CustomTransition / src / com.example.android.customtransition /

ChangeColor.java

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