• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 android.support.v17.leanback.widget;
18 
19 import android.animation.ObjectAnimator;
20 import android.animation.PropertyValuesHolder;
21 import android.util.Property;
22 import android.view.animation.LinearInterpolator;
23 
24 /**
25  * ParallaxTarget is responsible for updating the target through the {@link #update(float)} method
26  * or the {@link #directUpdate(Number)} method when {@link #isDirectMapping()} is true.
27  * When {@link #isDirectMapping()} is false, {@link ParallaxEffect} transforms the values of
28  * {@link Parallax}, which represents the current state of UI, into a float value between 0 and 1.
29  * That float value is passed into {@link #update(float)} method.
30  */
31 public abstract class ParallaxTarget {
32 
33     /**
34      * Implementation class is supposed to update target with the provided fraction
35      * (between 0 and 1). The fraction represents percentage of completed change (e.g. scroll) on
36      * target. Called only when {@link #isDirectMapping()} is false.
37      *
38      * @param fraction Fraction between 0 to 1.
39      * @see #isDirectMapping()
40      */
update(float fraction)41     public void update(float fraction) {
42     }
43 
44     /**
45      * Returns true if the ParallaxTarget is directly mapping from source value,
46      * {@link #directUpdate(Number)} will be used to update value, otherwise update(fraction) will
47      * be called to update value. Default implementation returns false.
48      *
49      * @return True if direct mapping, false otherwise.
50      * @see #directUpdate(Number)
51      * @see #update(float)
52      */
isDirectMapping()53     public boolean isDirectMapping() {
54         return false;
55     }
56 
57     /**
58      * Directly update the target using a float or int value. Called when {@link #isDirectMapping()}
59      * is true.
60      *
61      * @param value Either int or float value.
62      * @see #isDirectMapping()
63      */
directUpdate(Number value)64     public void directUpdate(Number value) {
65     }
66 
67     /**
68      * PropertyValuesHolderTarget is an implementation of {@link ParallaxTarget} that uses
69      * {@link PropertyValuesHolder} to update the target object.
70      */
71     public static final class PropertyValuesHolderTarget extends ParallaxTarget {
72 
73         /**
74          * We simulate a parallax effect on target object using an ObjectAnimator. PSEUDO_DURATION
75          * is used on the ObjectAnimator.
76          */
77         private static final long PSEUDO_DURATION = 1000000;
78 
79         private final ObjectAnimator mAnimator;
80         private float mFraction;
81 
PropertyValuesHolderTarget(Object targetObject, PropertyValuesHolder values)82         public PropertyValuesHolderTarget(Object targetObject, PropertyValuesHolder values) {
83             mAnimator = ObjectAnimator.ofPropertyValuesHolder(targetObject, values);
84             mAnimator.setInterpolator(new LinearInterpolator());
85             mAnimator.setDuration(PSEUDO_DURATION);
86         }
87 
88         @Override
update(float fraction)89         public void update(float fraction) {
90             mFraction = fraction;
91             mAnimator.setCurrentPlayTime((long) (PSEUDO_DURATION * fraction));
92         }
93 
94     }
95 
96     /**
97      * DirectPropertyTarget is to support direct mapping into either Integer Property or Float
98      * Property. App uses convenient method {@link ParallaxEffect#target(Object, Property)} to
99      * add a direct mapping.
100      * @param <T> Type of target object.
101      * @param <V> Type of value, either Integer or Float.
102      */
103     public static final class DirectPropertyTarget<T extends Object, V extends Number>
104             extends ParallaxTarget {
105 
106         Object mObject;
107         Property<T, V> mProperty;
108 
109         /**
110          * @param targetObject Target object for perform Parallax
111          * @param property     Target property, either an Integer Property or a Float Property.
112          */
DirectPropertyTarget(Object targetObject, Property<T, V> property)113         public DirectPropertyTarget(Object targetObject, Property<T, V> property) {
114             mObject = targetObject;
115             mProperty = property;
116         }
117 
118         /**
119          * Returns true as DirectPropertyTarget receives a number to update Property in
120          * {@link #directUpdate(Number)}.
121          */
122         @Override
isDirectMapping()123         public boolean isDirectMapping() {
124             return true;
125         }
126 
127         @Override
directUpdate(Number value)128         public void directUpdate(Number value) {
129             mProperty.set((T) mObject, (V) value);
130         }
131     }
132 }
133