105de4b68e45fc22c867d49ab88e2bdfd599bf7ccDake Gu/* 205de4b68e45fc22c867d49ab88e2bdfd599bf7ccDake Gu * Copyright (C) 2016 The Android Open Source Project 305de4b68e45fc22c867d49ab88e2bdfd599bf7ccDake Gu * 4e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * Licensed under the Apache License, Version 2.0 (the "License"); 5e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * you may not use this file except in compliance with the License. 6e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * You may obtain a copy of the License at 705de4b68e45fc22c867d49ab88e2bdfd599bf7ccDake Gu * 8e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * http://www.apache.org/licenses/LICENSE-2.0 905de4b68e45fc22c867d49ab88e2bdfd599bf7ccDake Gu * 10e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * Unless required by applicable law or agreed to in writing, software 11e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * distributed under the License is distributed on an "AS IS" BASIS, 12e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * See the License for the specific language governing permissions and 14e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * limitations under the License. 1505de4b68e45fc22c867d49ab88e2bdfd599bf7ccDake Gu */ 1605de4b68e45fc22c867d49ab88e2bdfd599bf7ccDake Gu 17e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gupackage android.support.v17.leanback.widget; 1805de4b68e45fc22c867d49ab88e2bdfd599bf7ccDake Gu 19e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Guimport android.support.annotation.CallSuper; 2005de4b68e45fc22c867d49ab88e2bdfd599bf7ccDake Guimport android.support.v17.leanback.widget.ParallaxEffect.FloatEffect; 2105de4b68e45fc22c867d49ab88e2bdfd599bf7ccDake Guimport android.support.v17.leanback.widget.ParallaxEffect.IntEffect; 22e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Guimport android.util.Property; 23e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu 24e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Guimport java.util.ArrayList; 25e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Guimport java.util.Collections; 26e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Guimport java.util.List; 2705de4b68e45fc22c867d49ab88e2bdfd599bf7ccDake Gu 2805de4b68e45fc22c867d49ab88e2bdfd599bf7ccDake Gu/** 29e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * Parallax tracks a list of dynamic {@link Property}s typically representing foreground UI 30e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * element positions on screen. Parallax keeps a list of {@link ParallaxEffect} objects which define 31e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * rules to mapping property values to {@link ParallaxTarget}. 32e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * 33e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * <p> 34bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * Example: 35bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * <code> 36bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * // when Property "var1" changes from 15 to max value, perform parallax effect to 37bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * // change myView's translationY from 0 to 100. 38bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * Parallax<IntProperty> parallax = new Parallax<IntProperty>() {...}; 39bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * p1 = parallax.addProperty("var1"); 40bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * parallax.addEffect(p1.at(15), p1.atMax()) 41bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * .target(myView, PropertyValuesHolder.ofFloat("translationY", 0, 100)); 42bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * </code> 43bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * </p> 44bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * 45bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * <p> 46bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * To create a {@link ParallaxEffect}, user calls {@link #addEffect(PropertyMarkerValue[])} with a 47bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * list of {@link PropertyMarkerValue} which defines the range of {@link Parallax.IntProperty} or 48bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * {@link Parallax.FloatProperty}. Then user adds {@link ParallaxTarget} into 49bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * {@link ParallaxEffect}. 50bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * </p> 51bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * <p> 52bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * App may subclass {@link Parallax.IntProperty} or {@link Parallax.FloatProperty} to supply 53bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * additional information about how to retrieve Property value. {@link RecyclerViewParallax} is 54bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * a great example of Parallax implementation tracking child view positions on screen. 55e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * </p> 56e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * <p> 57e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * <ul>Restrictions of properties 58bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * <li>FloatProperty and IntProperty cannot be mixed in one Parallax</li> 59e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * <li>Values must be in ascending order.</li> 60e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * <li>If the UI element is unknown above screen, use UNKNOWN_BEFORE.</li> 61e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * <li>if the UI element is unknown below screen, use UNKNOWN_AFTER.</li> 62e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * <li>UNKNOWN_BEFORE and UNKNOWN_AFTER are not allowed to be next to each other.</li> 63e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * </ul> 64bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * These rules will be verified at runtime. 65e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * </p> 66bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * <p> 67bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * Subclass must override {@link #updateValues()} to update property values and perform 68e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * {@link ParallaxEffect}s. Subclass may call {@link #updateValues()} automatically e.g. 69e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * {@link RecyclerViewParallax} calls {@link #updateValues()} in RecyclerView scrolling. App might 70e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * call {@link #updateValues()} manually when Parallax is unaware of the value change. For example, 71e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * when a slide transition is running, {@link RecyclerViewParallax} is unaware of translation value 72e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * changes; it's the app's responsibility to call {@link #updateValues()} in every frame of 73e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * animation. 74e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * </p> 75bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * @paramSubclass of {@link Parallax.IntProperty} or {@link Parallax.FloatProperty} 7605de4b68e45fc22c867d49ab88e2bdfd599bf7ccDake Gu */ 77bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gupublic abstract class Parallax<PropertyT extends android.util.Property> { 7805de4b68e45fc22c867d49ab88e2bdfd599bf7ccDake Gu 79e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu /** 80e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * Class holding a fixed value for a Property in {@link Parallax}. 81e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * @param Class of the property, e.g. {@link IntProperty} or {@link FloatProperty}. 82e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu */ 83e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu public static class PropertyMarkerValue<PropertyT> { 84e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu private final PropertyT mProperty; 85e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu 86e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu public PropertyMarkerValue(PropertyT property) { 87e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu mProperty = property; 88e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu } 89e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu 90e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu /** 91e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * @return Associated property. 92e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu */ 93e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu public PropertyT getProperty() { 94e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu return mProperty; 95e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu } 96e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu } 97e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu 98e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu /** 99e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * IntProperty provide access to an index based integer type property inside 100bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * {@link Parallax}. The IntProperty typically represents UI element position inside 101bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * {@link Parallax}. 102e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu */ 103bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu public static class IntProperty extends Property<Parallax, Integer> { 104e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu 105e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu /** 106e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * Property value is unknown and it's smaller than minimal value of Parallax. For 107e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * example if a child is not created and before the first visible child of RecyclerView. 108e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu */ 109e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu public static final int UNKNOWN_BEFORE = Integer.MIN_VALUE; 110e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu 111e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu /** 112bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * Property value is unknown and it's larger than {@link Parallax#getMaxValue()}. For 113e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * example if a child is not created and after the last visible child of RecyclerView. 114e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu */ 115e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu public static final int UNKNOWN_AFTER = Integer.MAX_VALUE; 116e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu 117e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu private final int mIndex; 118e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu 119e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu /** 120e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * Constructor. 121e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * 122e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * @param name Name of this Property. 123bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * @param index Index of this Property inside {@link Parallax}. 124e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu */ 125e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu public IntProperty(String name, int index) { 126e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu super(Integer.class, name); 127e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu mIndex = index; 128e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu } 129e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu 130e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu @Override 131bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu public final Integer get(Parallax object) { 132bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu return object.getIntPropertyValue(mIndex); 133e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu } 134e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu 135e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu @Override 136bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu public final void set(Parallax object, Integer value) { 137bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu object.setIntPropertyValue(mIndex, value); 138e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu } 139e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu 140e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu /** 141bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * @return Index of this Property in {@link Parallax}. 142e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu */ 143e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu public final int getIndex() { 144e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu return mIndex; 145e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu } 146e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu 147e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu /** 148bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * Fast version of get() method that returns a primitive int value of the Property. 149bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * @param object The Parallax object that owns this Property. 150bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * @return Int value of the Property. 151e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu */ 152bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu public final int getValue(Parallax object) { 153bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu return object.getIntPropertyValue(mIndex); 154e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu } 155e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu 156e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu /** 157bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * Fast version of set() method that takes a primitive int value into the Property. 158e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * 159bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * @param object The Parallax object that owns this Property. 160bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * @param value Int value of the Property. 161e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu */ 162bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu public final void setValue(Parallax object, int value) { 163bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu object.setIntPropertyValue(mIndex, value); 164e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu } 165e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu 166e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu /** 167bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * Creates an {@link PropertyMarkerValue} object for the absolute marker value. 168e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * 169bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * @param absoluteValue The integer marker value. 170bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * @return A new {@link PropertyMarkerValue} object. 171e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu */ 172bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu public final PropertyMarkerValue atAbsolute(int absoluteValue) { 173bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu return new IntPropertyMarkerValue(this, absoluteValue, 0f); 174e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu } 175e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu 176e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu /** 177bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * Creates an {@link PropertyMarkerValue} object for the marker value representing 178bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * {@link Parallax#getMaxValue()}. 179e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * 180bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * @return A new {@link PropertyMarkerValue} object. 181e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu */ 182bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu public final PropertyMarkerValue atMax() { 183bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu return new IntPropertyMarkerValue(this, 0, 1f); 184e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu } 185e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu 186e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu /** 187bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * Creates an {@link PropertyMarkerValue} object for the marker value representing 0. 188e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * 189bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * @return A new {@link PropertyMarkerValue} object. 190e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu */ 191bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu public final PropertyMarkerValue atMin() { 192bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu return new IntPropertyMarkerValue(this, 0); 193e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu } 194e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu 195e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu /** 196bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * Creates an {@link PropertyMarkerValue} object for a fraction of 197bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * {@link Parallax#getMaxValue()}. 198e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * 199bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * @param fractionOfMaxValue 0 to 1 fraction to multiply with 200bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * {@link Parallax#getMaxValue()} for 201bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * the marker value. 202bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * @return A new {@link PropertyMarkerValue} object. 203e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu */ 204bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu public final PropertyMarkerValue atFraction(float fractionOfMaxValue) { 205bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu return new IntPropertyMarkerValue(this, 0, fractionOfMaxValue); 20605de4b68e45fc22c867d49ab88e2bdfd599bf7ccDake Gu } 207e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu 208bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu /** 209bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * Create an {@link PropertyMarkerValue} object by multiplying the fraction with 210bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * {@link Parallax#getMaxValue()} and adding offsetValue to it. 211bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * 212bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * @param offsetValue An offset integer value to be added to marker 213bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * value. 214bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * @param fractionOfMaxParentVisibleSize 0 to 1 fraction to multiply with 215bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * {@link Parallax#getMaxValue()} for 216bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * the marker value. 217bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * @return A new {@link PropertyMarkerValue} object. 218bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu */ 219bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu public final PropertyMarkerValue at(int offsetValue, 220bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu float fractionOfMaxParentVisibleSize) { 221bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu return new IntPropertyMarkerValue(this, offsetValue, fractionOfMaxParentVisibleSize); 222e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu } 223e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu } 22405de4b68e45fc22c867d49ab88e2bdfd599bf7ccDake Gu 22505de4b68e45fc22c867d49ab88e2bdfd599bf7ccDake Gu /** 226e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * Implementation of {@link PropertyMarkerValue} for {@link IntProperty}. 227e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu */ 228bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu static class IntPropertyMarkerValue extends PropertyMarkerValue<IntProperty> { 229e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu private final int mValue; 230e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu private final float mFactionOfMax; 231e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu 232bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu IntPropertyMarkerValue(IntProperty property, int value) { 233e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu this(property, value, 0f); 234e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu } 235e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu 236bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu IntPropertyMarkerValue(IntProperty property, int value, float fractionOfMax) { 237e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu super(property); 238e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu mValue = value; 239e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu mFactionOfMax = fractionOfMax; 240e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu } 241e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu 242e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu /** 243e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * @return The marker value of integer type. 244e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu */ 245bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu final int getMarkerValue(Parallax source) { 246e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu return mFactionOfMax == 0 ? mValue : mValue + Math.round(source 247e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu .getMaxValue() * mFactionOfMax); 248e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu } 249e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu } 250e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu 251e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu /** 252e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * FloatProperty provide access to an index based integer type property inside 253bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * {@link Parallax}. The FloatProperty typically represents UI element position inside 254bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * {@link Parallax}. 255e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu */ 256bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu public static class FloatProperty extends Property<Parallax, Float> { 257e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu 258e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu /** 259e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * Property value is unknown and it's smaller than minimal value of Parallax. For 260e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * example if a child is not created and before the first visible child of RecyclerView. 261e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu */ 262e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu public static final float UNKNOWN_BEFORE = -Float.MAX_VALUE; 263e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu 264e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu /** 265bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * Property value is unknown and it's larger than {@link Parallax#getMaxValue()}. For 266e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * example if a child is not created and after the last visible child of RecyclerView. 267e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu */ 268e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu public static final float UNKNOWN_AFTER = Float.MAX_VALUE; 269e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu 270e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu private final int mIndex; 271e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu 272e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu /** 273e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * Constructor. 274e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * 275e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * @param name Name of this Property. 276bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * @param index Index of this Property inside {@link Parallax}. 277e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu */ 278e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu public FloatProperty(String name, int index) { 279e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu super(Float.class, name); 280e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu mIndex = index; 281e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu } 282e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu 283e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu @Override 284bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu public final Float get(Parallax object) { 285bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu return object.getFloatPropertyValue(mIndex); 286e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu } 287e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu 288e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu @Override 289bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu public final void set(Parallax object, Float value) { 290bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu object.setFloatPropertyValue(mIndex, value); 291e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu } 292e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu 293e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu /** 294bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * @return Index of this Property in {@link Parallax}. 295e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu */ 296e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu public final int getIndex() { 297e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu return mIndex; 298e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu } 299e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu 300e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu /** 301bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * Fast version of get() method that returns a primitive int value of the Property. 302bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * @param object The Parallax object that owns this Property. 303bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * @return Float value of the Property. 304e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu */ 305bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu public final float getValue(Parallax object) { 306bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu return object.getFloatPropertyValue(mIndex); 307e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu } 308e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu 309e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu /** 310bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * Fast version of set() method that takes a primitive float value into the Property. 311e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * 312bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * @param object The Parallax object that owns this Property. 313bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * @param value Float value of the Property. 314e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu */ 315bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu public final void setValue(Parallax object, float value) { 316bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu object.setFloatPropertyValue(mIndex, value); 317e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu } 318e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu 319e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu /** 320bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * Creates an {@link PropertyMarkerValue} object for the absolute marker value. 321e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * 322bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * @param markerValue The float marker value. 323bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * @return A new {@link PropertyMarkerValue} object. 324e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu */ 325bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu public final PropertyMarkerValue atAbsolute(float markerValue) { 326bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu return new FloatPropertyMarkerValue(this, markerValue, 0f); 327e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu } 328e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu 329e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu /** 330bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * Creates an {@link PropertyMarkerValue} object for the marker value representing 331bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * {@link Parallax#getMaxValue()}. 332e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * 333bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * @return A new {@link PropertyMarkerValue} object. 334e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu */ 335bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu public final PropertyMarkerValue atMax() { 336bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu return new FloatPropertyMarkerValue(this, 0, 1f); 33705de4b68e45fc22c867d49ab88e2bdfd599bf7ccDake Gu } 338e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu 339e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu /** 340bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * Creates an {@link PropertyMarkerValue} object for the marker value representing 0. 341e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * 342bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * @return A new {@link PropertyMarkerValue} object. 343e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu */ 344bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu public final PropertyMarkerValue atMin() { 345bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu return new FloatPropertyMarkerValue(this, 0); 346e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu } 347e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu 348e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu /** 349bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * Creates an {@link PropertyMarkerValue} object for a fraction of 350bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * {@link Parallax#getMaxValue()}. 351e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * 352bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * @param fractionOfMaxParentVisibleSize 0 to 1 fraction to multiply with 353bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * {@link Parallax#getMaxValue()} for 354bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * the marker value. 355bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * @return A new {@link PropertyMarkerValue} object. 356e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu */ 357bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu public final PropertyMarkerValue atFraction(float fractionOfMaxParentVisibleSize) { 358bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu return new FloatPropertyMarkerValue(this, 0, fractionOfMaxParentVisibleSize); 359e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu } 360e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu 361bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu /** 362bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * Create an {@link PropertyMarkerValue} object by multiplying the fraction with 363bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * {@link Parallax#getMaxValue()} and adding offsetValue to it. 364bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * 365bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * @param offsetValue An offset float value to be added to marker value. 366bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * @param fractionOfMaxParentVisibleSize 0 to 1 fraction to multiply with 367bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * {@link Parallax#getMaxValue()} for 368bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * the marker value. 369bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * @return A new {@link PropertyMarkerValue} object. 370bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu */ 371bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu public final PropertyMarkerValue at(float offsetValue, 372bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu float fractionOfMaxParentVisibleSize) { 373bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu return new FloatPropertyMarkerValue(this, offsetValue, fractionOfMaxParentVisibleSize); 374e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu } 375e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu } 376e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu 377e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu /** 378e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * Implementation of {@link PropertyMarkerValue} for {@link FloatProperty}. 379e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu */ 380bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu static class FloatPropertyMarkerValue extends PropertyMarkerValue<FloatProperty> { 381e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu private final float mValue; 382e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu private final float mFactionOfMax; 383e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu 384bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu FloatPropertyMarkerValue(FloatProperty property, float value) { 385e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu this(property, value, 0f); 386e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu } 387e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu 388bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu FloatPropertyMarkerValue(FloatProperty property, float value, float fractionOfMax) { 389e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu super(property); 390e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu mValue = value; 391e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu mFactionOfMax = fractionOfMax; 392e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu } 393e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu 394e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu /** 395e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * @return The marker value. 396e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu */ 397bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu final float getMarkerValue(Parallax source) { 398e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu return mFactionOfMax == 0 ? mValue : mValue + source.getMaxValue() 399e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * mFactionOfMax; 40005de4b68e45fc22c867d49ab88e2bdfd599bf7ccDake Gu } 40105de4b68e45fc22c867d49ab88e2bdfd599bf7ccDake Gu } 40205de4b68e45fc22c867d49ab88e2bdfd599bf7ccDake Gu 403e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu final List<PropertyT> mProperties = new ArrayList<PropertyT>(); 404e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu final List<PropertyT> mPropertiesReadOnly = Collections.unmodifiableList(mProperties); 405e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu 406bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu private int[] mValues = new int[4]; 407bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu private float[] mFloatValues = new float[4]; 408bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu 409bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu private final List<ParallaxEffect> mEffects = new ArrayList<ParallaxEffect>(4); 410bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu 41105de4b68e45fc22c867d49ab88e2bdfd599bf7ccDake Gu /** 412bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * Return the max value which is typically size of parent visible area, e.g. RecyclerView's 413bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * height if we are tracking Y position of a child. The size can be used to calculate marker 414bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * value using the provided fraction of FloatPropertyMarkerValue. 415bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * 416bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * @return Size of parent visible area. 417bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * @see IntPropertyMarkerValue#IntPropertyMarkerValue(IntProperty, int, float) 418bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * @see FloatPropertyMarkerValue#FloatPropertyMarkerValue(FloatProperty, float, float) 419e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu */ 420bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu public abstract float getMaxValue(); 421bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu 422bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu /** 423bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * Get index based property value. 424bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * 425bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * @param index Index of the property. 426bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * @return Value of the property. 427bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu */ 428bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu final int getIntPropertyValue(int index) { 429bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu return mValues[index]; 430e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu } 431e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu 432e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu /** 433bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * Set index based property value. 43405de4b68e45fc22c867d49ab88e2bdfd599bf7ccDake Gu * 435bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * @param index Index of the property. 436bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * @param value Value of the property. 43705de4b68e45fc22c867d49ab88e2bdfd599bf7ccDake Gu */ 438bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu final void setIntPropertyValue(int index, int value) { 439bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu if (index >= mProperties.size()) { 440bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu throw new ArrayIndexOutOfBoundsException(); 441bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu } 442bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu mValues[index] = value; 443bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu } 444e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu 445e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu /** 446bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * Add a new IntProperty in the Parallax object. App may override 447bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * {@link #createProperty(String, int)}. 448e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * 449bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * @param name Name of the property. 450e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * @return Newly created Property object. 451bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * @see #createProperty(String, int) 452e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu */ 453bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu public final PropertyT addProperty(String name) { 454bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu int newPropertyIndex = mProperties.size(); 455bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu PropertyT property = createProperty(name, newPropertyIndex); 456bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu if (property instanceof IntProperty) { 457bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu int size = mValues.length; 458bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu if (size == newPropertyIndex) { 459bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu int[] newValues = new int[size * 2]; 460bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu for (int i = 0; i < size; i++) { 461bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu newValues[i] = mValues[i]; 462bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu } 463bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu mValues = newValues; 464bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu } 465bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu mValues[newPropertyIndex] = IntProperty.UNKNOWN_AFTER; 466bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu } else if (property instanceof FloatProperty) { 467bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu int size = mFloatValues.length; 468bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu if (size == newPropertyIndex) { 469bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu float[] newValues = new float[size * 2]; 470bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu for (int i = 0; i < size; i++) { 471bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu newValues[i] = mFloatValues[i]; 472bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu } 473bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu mFloatValues = newValues; 474bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu } 475bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu mFloatValues[newPropertyIndex] = FloatProperty.UNKNOWN_AFTER; 476bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu } else { 477bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu throw new IllegalArgumentException("Invalid Property type"); 478bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu } 479bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu mProperties.add(property); 480bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu return property; 481bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu } 482e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu 483e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu /** 484e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * Verify sanity of property values, throws RuntimeException if fails. The property values 485e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * must be in ascending order. UNKNOW_BEFORE and UNKNOWN_AFTER are not allowed to be next to 486e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * each other. 487e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu */ 488bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu void verifyIntProperties() throws IllegalStateException { 489bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu if (mProperties.size() < 2) { 490bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu return; 491bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu } 492bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu int last = getIntPropertyValue(0); 493bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu for (int i = 1; i < mProperties.size(); i++) { 494bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu int v = getIntPropertyValue(i); 495bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu if (v < last) { 496bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu throw new IllegalStateException(String.format("Parallax Property[%d]\"%s\" is" 497bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu + " smaller than Property[%d]\"%s\"", 498bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu i, mProperties.get(i).getName(), 499bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu i - 1, mProperties.get(i - 1).getName())); 500bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu } else if (last == IntProperty.UNKNOWN_BEFORE && v == IntProperty.UNKNOWN_AFTER) { 501bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu throw new IllegalStateException(String.format("Parallax Property[%d]\"%s\" is" 502bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu + " UNKNOWN_BEFORE and Property[%d]\"%s\" is UNKNOWN_AFTER", 503bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu i - 1, mProperties.get(i - 1).getName(), 504bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu i, mProperties.get(i).getName())); 505bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu } 506bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu last = v; 507bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu } 508bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu } 509bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu 510bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu final void verifyFloatProperties() throws IllegalStateException { 511bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu if (mProperties.size() < 2) { 512bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu return; 513bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu } 514bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu float last = getFloatPropertyValue(0); 515bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu for (int i = 1; i < mProperties.size(); i++) { 516bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu float v = getFloatPropertyValue(i); 517bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu if (v < last) { 518bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu throw new IllegalStateException(String.format("Parallax Property[%d]\"%s\" is" 519bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu + " smaller than Property[%d]\"%s\"", 520bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu i, mProperties.get(i).getName(), 521bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu i - 1, mProperties.get(i - 1).getName())); 522bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu } else if (last == FloatProperty.UNKNOWN_BEFORE && v 523bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu == FloatProperty.UNKNOWN_AFTER) { 524bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu throw new IllegalStateException(String.format("Parallax Property[%d]\"%s\" is" 525bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu + " UNKNOWN_BEFORE and Property[%d]\"%s\" is UNKNOWN_AFTER", 526bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu i - 1, mProperties.get(i - 1).getName(), 527bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu i, mProperties.get(i).getName())); 528bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu } 529bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu last = v; 530bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu } 531bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu } 532bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu 533bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu /** 534bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * Get index based property value. 535bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * 536bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * @param index Index of the property. 537bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * @return Value of the property. 538bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu */ 539bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu final float getFloatPropertyValue(int index) { 540bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu return mFloatValues[index]; 541bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu } 542bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu 543bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu /** 544bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * Set index based property value. 545bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * 546bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * @param index Index of the property. 547bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * @param value Value of the property. 548bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu */ 549bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu final void setFloatPropertyValue(int index, float value) { 550bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu if (index >= mProperties.size()) { 551bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu throw new ArrayIndexOutOfBoundsException(); 552bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu } 553bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu mFloatValues[index] = value; 554bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu } 555bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu 556bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu /** 557bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * @return A unmodifiable list of properties. 558bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu */ 559bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu public final List<PropertyT> getProperties() { 560bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu return mPropertiesReadOnly; 561bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu } 562bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu 563bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu /** 564bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * Create a new Property object. App does not directly call this method. See 565bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * {@link #addProperty(String)}. 566bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * 567bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * @param index Index of the property in this Parallax object. 568bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu * @return Newly created Property object. 569bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu */ 570bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu public abstract PropertyT createProperty(String name, int index); 571e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu 572e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu /** 573e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * Update property values and perform {@link ParallaxEffect}s. Subclass may override and call 574e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * super.updateValues() after updated properties values. 575e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu */ 576e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu @CallSuper 577e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu public void updateValues() { 578e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu for (int i = 0; i < mEffects.size(); i++) { 579e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu mEffects.get(i).performMapping(this); 580e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu } 58105de4b68e45fc22c867d49ab88e2bdfd599bf7ccDake Gu } 58205de4b68e45fc22c867d49ab88e2bdfd599bf7ccDake Gu 58305de4b68e45fc22c867d49ab88e2bdfd599bf7ccDake Gu /** 584e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * Returns a list of {@link ParallaxEffect} object which defines rules to perform mapping to 585e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * multiple {@link ParallaxTarget}s. 58605de4b68e45fc22c867d49ab88e2bdfd599bf7ccDake Gu * 58705de4b68e45fc22c867d49ab88e2bdfd599bf7ccDake Gu * @return A list of {@link ParallaxEffect} object. 58805de4b68e45fc22c867d49ab88e2bdfd599bf7ccDake Gu */ 58905de4b68e45fc22c867d49ab88e2bdfd599bf7ccDake Gu public List<ParallaxEffect> getEffects() { 59005de4b68e45fc22c867d49ab88e2bdfd599bf7ccDake Gu return mEffects; 59105de4b68e45fc22c867d49ab88e2bdfd599bf7ccDake Gu } 59205de4b68e45fc22c867d49ab88e2bdfd599bf7ccDake Gu 59305de4b68e45fc22c867d49ab88e2bdfd599bf7ccDake Gu /** 59405de4b68e45fc22c867d49ab88e2bdfd599bf7ccDake Gu * Remove the {@link ParallaxEffect} object. 59505de4b68e45fc22c867d49ab88e2bdfd599bf7ccDake Gu * 59605de4b68e45fc22c867d49ab88e2bdfd599bf7ccDake Gu * @param effect The {@link ParallaxEffect} object to remove. 59705de4b68e45fc22c867d49ab88e2bdfd599bf7ccDake Gu */ 59805de4b68e45fc22c867d49ab88e2bdfd599bf7ccDake Gu public void removeEffect(ParallaxEffect effect) { 59905de4b68e45fc22c867d49ab88e2bdfd599bf7ccDake Gu mEffects.remove(effect); 60005de4b68e45fc22c867d49ab88e2bdfd599bf7ccDake Gu } 60105de4b68e45fc22c867d49ab88e2bdfd599bf7ccDake Gu 60205de4b68e45fc22c867d49ab88e2bdfd599bf7ccDake Gu /** 60305de4b68e45fc22c867d49ab88e2bdfd599bf7ccDake Gu * Remove all {@link ParallaxEffect} objects. 60405de4b68e45fc22c867d49ab88e2bdfd599bf7ccDake Gu */ 60505de4b68e45fc22c867d49ab88e2bdfd599bf7ccDake Gu public void removeAllEffects() { 60605de4b68e45fc22c867d49ab88e2bdfd599bf7ccDake Gu mEffects.clear(); 60705de4b68e45fc22c867d49ab88e2bdfd599bf7ccDake Gu } 60805de4b68e45fc22c867d49ab88e2bdfd599bf7ccDake Gu 60905de4b68e45fc22c867d49ab88e2bdfd599bf7ccDake Gu /** 61005de4b68e45fc22c867d49ab88e2bdfd599bf7ccDake Gu * Create a {@link ParallaxEffect} object that will track source variable changes within a 61105de4b68e45fc22c867d49ab88e2bdfd599bf7ccDake Gu * provided set of ranges. 61205de4b68e45fc22c867d49ab88e2bdfd599bf7ccDake Gu * 613e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * @param ranges A list of marker values that defines the ranges. 61405de4b68e45fc22c867d49ab88e2bdfd599bf7ccDake Gu * @return Newly created ParallaxEffect object. 61505de4b68e45fc22c867d49ab88e2bdfd599bf7ccDake Gu */ 616bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu public ParallaxEffect addEffect(PropertyMarkerValue... ranges) { 617bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu ParallaxEffect effect; 618bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu if (ranges[0].getProperty() instanceof IntProperty) { 619bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu effect = new IntEffect(); 620bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu } else { 621bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu effect = new FloatEffect(); 622bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu } 6233778c4eaa62895085d33965ee391c8b21783cffaDake Gu effect.setPropertyRanges(ranges); 624bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu mEffects.add(effect); 62505de4b68e45fc22c867d49ab88e2bdfd599bf7ccDake Gu return effect; 62605de4b68e45fc22c867d49ab88e2bdfd599bf7ccDake Gu } 62705de4b68e45fc22c867d49ab88e2bdfd599bf7ccDake Gu 62805de4b68e45fc22c867d49ab88e2bdfd599bf7ccDake Gu} 629