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