Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 60adc3fb authored by Jon Miranda's avatar Jon Miranda
Browse files

Generalize SpringObjectAnimator.

This is in preparation for adding more springs to the state transitions.

Bug: 111698021
Change-Id: I32cd7894e940dae00895799280b244d68400d374
parent 982ff071
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
import static com.android.launcher3.LauncherState.BACKGROUND_APP;
import static com.android.launcher3.LauncherState.FAST_OVERVIEW;
import static com.android.launcher3.LauncherState.OVERVIEW;
import static com.android.launcher3.allapps.AllAppsTransitionController.ALL_APPS_PROGRESS_SPRING;
import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.launcher3.states.RotationHelper.REQUEST_LOCK;
import static com.android.quickstep.TouchConsumer.INTERACTION_NORMAL;
@@ -295,7 +296,8 @@ public interface ActivityControlHelper<T extends BaseDraggingActivity> {

            AnimatorSet anim = new AnimatorSet();
            if (!activity.getDeviceProfile().isVerticalBarLayout()) {
                Animator shiftAnim = new SpringObjectAnimator(activity.getAllAppsController(),
                Animator shiftAnim = new SpringObjectAnimator<>(activity.getAllAppsController(),
                        ALL_APPS_PROGRESS_SPRING, "allAppsSpringFromACH",
                        activity.getAllAppsController().getShiftRange(),
                        fromState.getVerticalProgress(activity),
                        endState.getVerticalProgress(activity));
+26 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2019 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;

/**
 * Progress is defined as a value with range [0, 1], and is specific to each implementor.
 * It is used when there is a transition from one state of the UI to another.
 */
public interface ProgressInterface {
    void setProgress(float progress);
    float getProgress();
}
 No newline at end of file
+7 −39
Original line number Diff line number Diff line
@@ -23,17 +23,16 @@ import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
import com.android.launcher3.LauncherStateManager.AnimationConfig;
import com.android.launcher3.LauncherStateManager.StateHandler;
import com.android.launcher3.ProgressInterface;
import com.android.launcher3.R;
import com.android.launcher3.anim.AnimationSuccessListener;
import com.android.launcher3.anim.AnimatorSetBuilder;
import com.android.launcher3.anim.SpringObjectAnimator;
import com.android.launcher3.anim.PropertySetter;
import com.android.launcher3.anim.SpringObjectAnimator.SpringProperty;
import com.android.launcher3.util.Themes;
import com.android.launcher3.views.ScrimView;

import androidx.dynamicanimation.animation.FloatPropertyCompat;
import androidx.dynamicanimation.animation.SpringAnimation;

/**
 * Handles AllApps view transition.
@@ -45,7 +44,8 @@ import androidx.dynamicanimation.animation.SpringAnimation;
 * If release velocity < THRES1, snap according to either top or bottom depending on whether it's
 * closer to top or closer to the page indicator.
 */
public class AllAppsTransitionController implements StateHandler, OnDeviceProfileChangeListener {
public class AllAppsTransitionController implements StateHandler, OnDeviceProfileChangeListener,
        ProgressInterface {

    public static final Property<AllAppsTransitionController, Float> ALL_APPS_PROGRESS =
            new Property<AllAppsTransitionController, Float>(Float.class, "allAppsProgress") {
@@ -74,40 +74,6 @@ public class AllAppsTransitionController implements StateHandler, OnDeviceProfil
        }
    };

    /**
     * Property that either sets the progress directly or animates the progress via a spring.
     */
    public static class AllAppsSpringProperty extends
            SpringProperty<AllAppsTransitionController, Float> {

        SpringAnimation mSpring;
        boolean useSpring = false;

        public AllAppsSpringProperty(SpringAnimation spring) {
            super(Float.class, "allAppsSpringProperty");
            mSpring = spring;
        }

        @Override
        public Float get(AllAppsTransitionController controller) {
            return controller.getProgress();
        }

        @Override
        public void set(AllAppsTransitionController controller, Float progress) {
            if (useSpring) {
                mSpring.animateToFinalPosition(progress);
            } else {
                controller.setProgress(progress);
            }
        }

        @Override
        public void switchToSpring() {
            useSpring = true;
        }
    }

    private AllAppsContainerView mAppsView;
    private ScrimView mScrimView;

@@ -161,6 +127,7 @@ public class AllAppsTransitionController implements StateHandler, OnDeviceProfil
     * @see #setState(LauncherState)
     * @see #setStateWithAnimation(LauncherState, AnimatorSetBuilder, AnimationConfig)
     */
    @Override
    public void setProgress(float progress) {
        mProgress = progress;
        mScrimView.setProgress(progress);
@@ -185,6 +152,7 @@ public class AllAppsTransitionController implements StateHandler, OnDeviceProfil
        }
    }

    @Override
    public float getProgress() {
        return mProgress;
    }
@@ -223,8 +191,8 @@ public class AllAppsTransitionController implements StateHandler, OnDeviceProfil
        Interpolator interpolator = config.userControlled ? LINEAR : toState == OVERVIEW
                ? builder.getInterpolator(ANIM_OVERVIEW_SCALE, FAST_OUT_SLOW_IN)
                : FAST_OUT_SLOW_IN;
        Animator anim = new SpringObjectAnimator(this, 1f / mShiftRange, mProgress,
                targetProgress);
        Animator anim = new SpringObjectAnimator<>(this, ALL_APPS_PROGRESS_SPRING,
                "allAppsSpringFromAATC", 1f / mShiftRange, mProgress, targetProgress);
        anim.setDuration(config.duration);
        anim.setInterpolator(builder.getInterpolator(ANIM_VERTICAL_PROGRESS, interpolator));
        anim.addListener(getProgressAnimatorListener());
+33 −14
Original line number Diff line number Diff line
@@ -23,12 +23,12 @@ import android.animation.ValueAnimator;
import android.util.Log;
import android.util.Property;

import com.android.launcher3.allapps.AllAppsTransitionController;
import com.android.launcher3.allapps.AllAppsTransitionController.AllAppsSpringProperty;
import com.android.launcher3.ProgressInterface;

import java.util.ArrayList;

import androidx.dynamicanimation.animation.DynamicAnimation.OnAnimationEndListener;
import androidx.dynamicanimation.animation.FloatPropertyCompat;
import androidx.dynamicanimation.animation.SpringAnimation;
import androidx.dynamicanimation.animation.SpringForce;

@@ -38,17 +38,17 @@ import static com.android.launcher3.config.FeatureFlags.QUICKSTEP_SPRINGS;
 * This animator allows for an object's property to be be controlled by an {@link ObjectAnimator} or
 * a {@link SpringAnimation}. It extends ValueAnimator so it can be used in an AnimatorSet.
 */
public class SpringObjectAnimator extends ValueAnimator {
public class SpringObjectAnimator<T extends ProgressInterface> extends ValueAnimator {

    private static final String TAG = "SpringObjectAnimator";
    private static boolean DEBUG = false;

    private AllAppsTransitionController mObject;
    private T mObject;
    private ObjectAnimator mObjectAnimator;
    private float[] mValues;

    private SpringAnimation mSpring;
    private AllAppsSpringProperty mProperty;
    private SpringProperty<T> mProperty;

    private ArrayList<AnimatorListener> mListeners;
    private boolean mSpringEnded = false;
@@ -58,16 +58,16 @@ public class SpringObjectAnimator extends ValueAnimator {
    private static final float SPRING_DAMPING_RATIO = 0.9f;
    private static final float SPRING_STIFFNESS = 600f;

    public SpringObjectAnimator(AllAppsTransitionController object, float minimumVisibleChange,
            float... values) {
    public SpringObjectAnimator(T object, FloatPropertyCompat<T> floatProperty,
            String name, float minimumVisibleChange, float... values) {
        mObject = object;
        mSpring = new SpringAnimation(object, AllAppsTransitionController.ALL_APPS_PROGRESS_SPRING);
        mSpring = new SpringAnimation(object, floatProperty);
        mSpring.setMinimumVisibleChange(minimumVisibleChange);
        mSpring.setSpring(new SpringForce(0)
                .setDampingRatio(SPRING_DAMPING_RATIO)
                .setStiffness(SPRING_STIFFNESS));
        mSpring.setStartVelocity(0.01f);
        mProperty = new AllAppsSpringProperty(mSpring);
        mProperty = new SpringProperty<T>(name, mSpring);
        mObjectAnimator = ObjectAnimator.ofFloat(object, mProperty, values);
        mValues = values;
        mListeners = new ArrayList<>();
@@ -261,13 +261,32 @@ public class SpringObjectAnimator extends ValueAnimator {
        mObjectAnimator.setCurrentPlayTime(playTime);
    }

    public static abstract class SpringProperty<T, V> extends Property<T, V> {
    public static class SpringProperty<T extends ProgressInterface> extends Property<T, Float> {

        public SpringProperty(Class<V> type, String name) {
            super(type, name);
        boolean useSpring = false;
        final SpringAnimation mSpring;

        public SpringProperty(String name, SpringAnimation spring) {
            super(Float.class, name);
            mSpring = spring;
        }

        public void switchToSpring() {
            useSpring = true;
        }

        abstract public void switchToSpring();
        @Override
        public Float get(T object) {
            return object.getProgress();
        }

        @Override
        public void set(T object, Float progress) {
            if (useSpring) {
                mSpring.animateToFinalPosition(progress);
            } else {
                object.setProgress(progress);
            }
        }
    }
}