diff options
author | TreeHugger Robot <treehugger-gerrit@google.com> | 2022-02-15 17:49:11 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2022-02-15 17:49:11 +0000 |
commit | fccae60a2478ea30f1b060f10ca8698e5bd5c6f0 (patch) | |
tree | 9795d6330519c74fe88b0a35579555be09f61b42 /src | |
parent | b70131e1ddc2b68a86c8aee9f85bfc394afb1f4a (diff) | |
parent | 12131a40fef26c56e2443d532cfefdd85d35e142 (diff) | |
download | Launcher3-fccae60a2478ea30f1b060f10ca8698e5bd5c6f0.tar.gz |
Merge "Add Z scaling during unfold to launcher"
Diffstat (limited to 'src')
3 files changed, 141 insertions, 5 deletions
diff --git a/src/com/android/launcher3/LauncherAnimUtils.java b/src/com/android/launcher3/LauncherAnimUtils.java index b56c0127ff..430039276e 100644 --- a/src/com/android/launcher3/LauncherAnimUtils.java +++ b/src/com/android/launcher3/LauncherAnimUtils.java @@ -27,6 +27,8 @@ import android.util.IntProperty; import android.view.View; import android.view.ViewGroup.LayoutParams; +import com.android.launcher3.util.MultiScalePropertyFactory; + public class LauncherAnimUtils { /** * Durations for various state animations. These are not defined in resources to allow @@ -64,6 +66,25 @@ public class LauncherAnimUtils { } }; + /** + * Property to set the scale of workspace and hotseat. The value is based on a combination + * of all the ones set, to have a smooth experience even in the case of overlapping scaling + * animation. + */ + public static final MultiScalePropertyFactory<View> SCALE_PROPERTY_FACTORY = + new MultiScalePropertyFactory<View>("scale_property") { + @Override + protected void apply(View view, float scale) { + view.setScaleX(scale); + view.setScaleY(scale); + } + }; + + public static final int SCALE_INDEX_UNFOLD_ANIMATION = 1; + public static final int SCALE_INDEX_UNLOCK_ANIMATION = 2; + public static final int SCALE_INDEX_WORKSPACE_STATE = 3; + public static final int SCALE_INDEX_REVEAL_ANIM = 4; + /** Increase the duration if we prevented the fling, as we are going against a high velocity. */ public static int blockedFlingDurationFactor(float velocity) { return (int) Utilities.boundToRange(Math.abs(velocity) / 2, 2f, 6f); diff --git a/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java b/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java index 1b9647afc0..98e785f47b 100644 --- a/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java +++ b/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java @@ -18,7 +18,8 @@ package com.android.launcher3; import static androidx.dynamicanimation.animation.DynamicAnimation.MIN_VISIBLE_CHANGE_SCALE; -import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY; +import static com.android.launcher3.LauncherAnimUtils.SCALE_INDEX_WORKSPACE_STATE; +import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY_FACTORY; import static com.android.launcher3.LauncherAnimUtils.VIEW_ALPHA; import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_X; import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_Y; @@ -42,6 +43,7 @@ import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_T import static com.android.launcher3.states.StateAnimationConfig.SKIP_SCRIM; import android.animation.ValueAnimator; +import android.util.FloatProperty; import android.view.View; import android.view.animation.Interpolator; @@ -62,6 +64,9 @@ import com.android.systemui.plugins.ResourceProvider; */ public class WorkspaceStateTransitionAnimation { + private static final FloatProperty<View> WORKSPACE_STATE_SCALE_PROPERTY = + SCALE_PROPERTY_FACTORY.get(SCALE_INDEX_WORKSPACE_STATE); + private final Launcher mLauncher; private final Workspace mWorkspace; @@ -117,7 +122,8 @@ public class WorkspaceStateTransitionAnimation { ((PendingAnimation) propertySetter).add(getSpringScaleAnimator(mLauncher, mWorkspace, mNewScale)); } else { - propertySetter.setFloat(mWorkspace, SCALE_PROPERTY, mNewScale, scaleInterpolator); + propertySetter.setFloat(mWorkspace, WORKSPACE_STATE_SCALE_PROPERTY, mNewScale, + scaleInterpolator); } mWorkspace.setPivotToScaleWithSelf(hotseat); @@ -128,7 +134,7 @@ public class WorkspaceStateTransitionAnimation { } else { Interpolator hotseatScaleInterpolator = config.getInterpolator(ANIM_HOTSEAT_SCALE, scaleInterpolator); - propertySetter.setFloat(hotseat, SCALE_PROPERTY, hotseatScale, + propertySetter.setFloat(hotseat, WORKSPACE_STATE_SCALE_PROPERTY, hotseatScale, hotseatScaleInterpolator); } @@ -205,9 +211,9 @@ public class WorkspaceStateTransitionAnimation { .setDampingRatio(damping) .setMinimumVisibleChange(MIN_VISIBLE_CHANGE_SCALE) .setEndValue(scale) - .setStartValue(SCALE_PROPERTY.get(v)) + .setStartValue(WORKSPACE_STATE_SCALE_PROPERTY.get(v)) .setStartVelocity(velocityPxPerS) - .build(v, SCALE_PROPERTY); + .build(v, WORKSPACE_STATE_SCALE_PROPERTY); } }
\ No newline at end of file diff --git a/src/com/android/launcher3/util/MultiScalePropertyFactory.java b/src/com/android/launcher3/util/MultiScalePropertyFactory.java new file mode 100644 index 0000000000..f27d0f0d86 --- /dev/null +++ b/src/com/android/launcher3/util/MultiScalePropertyFactory.java @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.launcher3.util; + +import android.util.ArrayMap; +import android.util.FloatProperty; + +import com.android.launcher3.Utilities; + +/** + * Allows to combine multiple values set by several sources. + * + * The various sources are meant to use [set], providing different `setterIndex` params. When it is + * not set, 0 is used. This is meant to cover the case multiple animations are going on at the same + * time. + * + * This class behaves similarly to [MultiValueAlpha], but is meant to be more abstract and reusable. + * It sets the multiplication of all values, bounded to the max and the min values. + * + * @param <T> Type where to apply the property. + */ +public abstract class MultiScalePropertyFactory<T> { + + private final String mName; + private final ArrayMap<Integer, MultiScaleProperty> mProperties = + new ArrayMap<Integer, MultiScaleProperty>(); + + // This is an optimization for cases when set is called repeatedly with the same setterIndex. + private float mMinOfOthers = 0; + private float mMaxOfOthers = 0; + private float mMultiplicationOfOthers = 0; + private Integer mLastIndexSet = -1; + private float mLastAggregatedValue = 1.0f; + + public MultiScalePropertyFactory(String name) { + mName = name; + } + + /** Returns the [MultiFloatProperty] associated with [inx], creating it if not present. */ + public MultiScaleProperty get(Integer index) { + return mProperties.computeIfAbsent(index, + (k) -> new MultiScaleProperty(index, mName + "_" + index)); + } + + + /** + * Each [setValue] will be aggregated with the other properties values created by the + * corresponding factory. + */ + class MultiScaleProperty extends FloatProperty<T> { + private final int mInx; + private float mValue = 1.0f; + + MultiScaleProperty(int inx, String name) { + super(name); + mInx = inx; + } + + @Override + public void setValue(T obj, float newValue) { + if (mLastIndexSet != mInx) { + mMinOfOthers = Float.MAX_VALUE; + mMaxOfOthers = Float.MIN_VALUE; + mMultiplicationOfOthers = 1.0f; + mProperties.forEach((key, property) -> { + if (key != mInx) { + mMinOfOthers = Math.min(mMinOfOthers, property.mValue); + mMaxOfOthers = Math.max(mMaxOfOthers, property.mValue); + mMultiplicationOfOthers *= property.mValue; + } + }); + mLastIndexSet = mInx; + } + float minValue = Math.min(mMinOfOthers, newValue); + float maxValue = Math.max(mMaxOfOthers, newValue); + float multValue = mMultiplicationOfOthers * newValue; + mLastAggregatedValue = Utilities.boundToRange(multValue, minValue, maxValue); + mValue = newValue; + apply(obj, mLastAggregatedValue); + } + + @Override + public Float get(T t) { + return mLastAggregatedValue; + } + + @Override + public String toString() { + return String.valueOf(mValue); + } + } + + /** Applies value to object after setValue method is called. */ + protected abstract void apply(T obj, float value); +} |