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

Commit ef129214 authored by Sunny Goyal's avatar Sunny Goyal
Browse files

Revert "Changing LauncherViewPropertyAnimator to use ValueAnimator"

Issue: Animations do not run

This reverts commit 33c04705.

Change-Id: I069379ac1003c4b11e008b82530c952a66604459
parent 33c04705
Loading
Loading
Loading
Loading
+217 −48
Original line number Diff line number Diff line
@@ -17,90 +17,259 @@
package com.android.launcher3;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.PropertyValuesHolder;
import android.animation.ValueAnimator;
import android.animation.Animator.AnimatorListener;
import android.animation.TimeInterpolator;
import android.view.View;

import com.android.launcher3.anim.AnimationLayerSet;
import android.view.ViewPropertyAnimator;

import java.util.ArrayList;
import java.util.EnumSet;

/**
 * Extension of {@link ValueAnimator} to provide an interface similar to
 * {@link android.view.ViewPropertyAnimator}.
 */
public class LauncherViewPropertyAnimator extends ValueAnimator {
public class LauncherViewPropertyAnimator extends Animator implements AnimatorListener {

    enum Properties {
            TRANSLATION_X,
            TRANSLATION_Y,
            SCALE_X,
            SCALE_Y,
            ROTATION_Y,
            ALPHA,
            START_DELAY,
            DURATION,
            INTERPOLATOR,
            WITH_LAYER
    }
    EnumSet<Properties> mPropertiesToSet = EnumSet.noneOf(Properties.class);
    ViewPropertyAnimator mViewPropertyAnimator;
    View mTarget;

    float mTranslationX;
    float mTranslationY;
    float mScaleX;
    float mScaleY;
    float mRotationY;
    float mAlpha;
    long mStartDelay;
    long mDuration;
    TimeInterpolator mInterpolator;
    ArrayList<Animator.AnimatorListener> mListeners = new ArrayList<>();
    boolean mRunning = false;
    FirstFrameAnimatorHelper mFirstFrameHelper;

    public LauncherViewPropertyAnimator(View target) {
        mTarget = target;
    }

    @Override
    public void addListener(Animator.AnimatorListener listener) {
        mListeners.add(listener);
    }

    @Override
    public void cancel() {
        if (mViewPropertyAnimator != null) {
            mViewPropertyAnimator.cancel();
        }
    }

    @Override
    public Animator clone() {
        throw new RuntimeException("Not implemented");
    }

    @Override
    public void end() {
        throw new RuntimeException("Not implemented");
    }

    @Override
    public long getDuration() {
        return mDuration;
    }

    @Override
    public ArrayList<Animator.AnimatorListener> getListeners() {
        return mListeners;
    }

    @Override
    public long getStartDelay() {
        return mStartDelay;
    }

    @Override
    public void onAnimationCancel(Animator animation) {
        for (int i = 0; i < mListeners.size(); i++) {
            Animator.AnimatorListener listener = mListeners.get(i);
            listener.onAnimationCancel(this);
        }
        mRunning = false;
    }

    @Override
    public void onAnimationEnd(Animator animation) {
        for (int i = 0; i < mListeners.size(); i++) {
            Animator.AnimatorListener listener = mListeners.get(i);
            listener.onAnimationEnd(this);
        }
        mRunning = false;
    }

    @Override
    public void onAnimationRepeat(Animator animation) {
        for (int i = 0; i < mListeners.size(); i++) {
            Animator.AnimatorListener listener = mListeners.get(i);
            listener.onAnimationRepeat(this);
        }
    }

    @Override
    public void onAnimationStart(Animator animation) {
        // This is the first time we get a handle to the internal ValueAnimator
        // used by the ViewPropertyAnimator.
        mFirstFrameHelper.onAnimationStart(animation);

        for (int i = 0; i < mListeners.size(); i++) {
            Animator.AnimatorListener listener = mListeners.get(i);
            listener.onAnimationStart(this);
        }
        mRunning = true;
    }

    @Override
    public boolean isRunning() {
        return mRunning;
    }

    private final View mTarget;
    private final ArrayList<PropertyValuesHolder> mProperties;
    @Override
    public boolean isStarted() {
        return mViewPropertyAnimator != null;
    }

    @Override
    public void removeAllListeners() {
        mListeners.clear();
    }

    @Override
    public void removeListener(Animator.AnimatorListener listener) {
        mListeners.remove(listener);
    }

    @Override
    public Animator setDuration(long duration) {
        mPropertiesToSet.add(Properties.DURATION);
        mDuration = duration;
        return this;
    }

    @Override
    public void setInterpolator(TimeInterpolator value) {
        mPropertiesToSet.add(Properties.INTERPOLATOR);
        mInterpolator = value;
    }

    private boolean mPrepared = false;
    @Override
    public void setStartDelay(long startDelay) {
        mPropertiesToSet.add(Properties.START_DELAY);
        mStartDelay = startDelay;
    }

    public LauncherViewPropertyAnimator(View view) {
        mTarget = view;
        mProperties = new ArrayList<>();
        setTarget(mTarget);
        addListener(new TransientStateUpdater(mTarget));
    @Override
    public void setTarget(Object target) {
        throw new RuntimeException("Not implemented");
    }

    @Override
    public void setupEndValues() {

    }

    @Override
    public void setupStartValues() {
    }

    @Override
    public void start() {
        if (!mPrepared) {
            mPrepared = true;
            setValues(mProperties.toArray(new PropertyValuesHolder[mProperties.size()]));
        mViewPropertyAnimator = mTarget.animate();

        // FirstFrameAnimatorHelper hooks itself up to the updates on the animator,
        // and then adjusts the play time to keep the first two frames jank-free
        mFirstFrameHelper = new FirstFrameAnimatorHelper(mViewPropertyAnimator, mTarget);

        if (mPropertiesToSet.contains(Properties.TRANSLATION_X)) {
            mViewPropertyAnimator.translationX(mTranslationX);
        }
        if (mPropertiesToSet.contains(Properties.TRANSLATION_Y)) {
            mViewPropertyAnimator.translationY(mTranslationY);
        }
        if (mPropertiesToSet.contains(Properties.SCALE_X)) {
            mViewPropertyAnimator.scaleX(mScaleX);
        }
        if (mPropertiesToSet.contains(Properties.ROTATION_Y)) {
            mViewPropertyAnimator.rotationY(mRotationY);
        }
        if (mPropertiesToSet.contains(Properties.SCALE_Y)) {
            mViewPropertyAnimator.scaleY(mScaleY);
        }
        if (mPropertiesToSet.contains(Properties.ALPHA)) {
            mViewPropertyAnimator.alpha(mAlpha);
        }
        if (mPropertiesToSet.contains(Properties.START_DELAY)) {
            mViewPropertyAnimator.setStartDelay(mStartDelay);
        }
        if (mPropertiesToSet.contains(Properties.DURATION)) {
            mViewPropertyAnimator.setDuration(mDuration);
        }
        if (mPropertiesToSet.contains(Properties.INTERPOLATOR)) {
            mViewPropertyAnimator.setInterpolator(mInterpolator);
        }
        if (mPropertiesToSet.contains(Properties.WITH_LAYER)) {
            mViewPropertyAnimator.withLayer();
        }
        mViewPropertyAnimator.setListener(this);
        mViewPropertyAnimator.start();
        LauncherAnimUtils.cancelOnDestroyActivity(this);
        super.start();
    }

    public LauncherViewPropertyAnimator translationX(float value) {
        mProperties.add(PropertyValuesHolder.ofFloat(View.TRANSLATION_X, value));
        mPropertiesToSet.add(Properties.TRANSLATION_X);
        mTranslationX = value;
        return this;
    }

    public LauncherViewPropertyAnimator translationY(float value) {
        mProperties.add(PropertyValuesHolder.ofFloat(View.TRANSLATION_Y, value));
        mPropertiesToSet.add(Properties.TRANSLATION_Y);
        mTranslationY = value;
        return this;
    }

    public LauncherViewPropertyAnimator scaleX(float value) {
        mProperties.add(PropertyValuesHolder.ofFloat(View.SCALE_X, value));
        mPropertiesToSet.add(Properties.SCALE_X);
        mScaleX = value;
        return this;
    }

    public LauncherViewPropertyAnimator scaleY(float value) {
        mProperties.add(PropertyValuesHolder.ofFloat(View.SCALE_Y, value));
        mPropertiesToSet.add(Properties.SCALE_Y);
        mScaleY = value;
        return this;
    }

    public LauncherViewPropertyAnimator alpha(float value) {
        mProperties.add(PropertyValuesHolder.ofFloat(View.ALPHA, value));
    public LauncherViewPropertyAnimator rotationY(float value) {
        mPropertiesToSet.add(Properties.ROTATION_Y);
        mRotationY = value;
        return this;
    }

    public LauncherViewPropertyAnimator withLayer() {
        AnimationLayerSet listener = new AnimationLayerSet();
        listener.addView(mTarget);
        addListener(listener);
    public LauncherViewPropertyAnimator alpha(float value) {
        mPropertiesToSet.add(Properties.ALPHA);
        mAlpha = value;
        return this;
    }

    private static class TransientStateUpdater extends AnimatorListenerAdapter {
        private final View mView;

        TransientStateUpdater(View v) {
            mView = v;
        }

        @Override
        public void onAnimationStart(Animator animation) {
            mView.setHasTransientState(true);
        }

        @Override
        public void onAnimationEnd(Animator animation) {
            mView.setHasTransientState(false);
        }
    public LauncherViewPropertyAnimator withLayer() {
        mPropertiesToSet.add(Properties.WITH_LAYER);
        return this;
    }
}
+6 −14
Original line number Diff line number Diff line
@@ -20,29 +20,23 @@ import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.view.View;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.HashSet;

/**
 * Helper class to automatically build view hardware layers for the duration of an animation.
 */
public class AnimationLayerSet extends AnimatorListenerAdapter {

    private final HashMap<View, Integer> mViewsToLayerTypeMap = new HashMap<>();
    private final HashSet<View> mViews = new HashSet<>();

    public void addView(View v) {
        mViewsToLayerTypeMap.put(v, v.getLayerType());
        mViews.add(v);
    }

    @Override
    public void onAnimationStart(Animator animation) {
        // Enable all necessary layers
        Iterator<Map.Entry<View, Integer>> itr = mViewsToLayerTypeMap.entrySet().iterator();
        while (itr.hasNext()) {
            Map.Entry<View, Integer> entry = itr.next();
            View v = entry.getKey();
            entry.setValue(v.getLayerType());
        for (View v : mViews) {
            v.setLayerType(View.LAYER_TYPE_HARDWARE, null);
            if (v.isAttachedToWindow() && v.getVisibility() == View.VISIBLE) {
                v.buildLayer();
@@ -52,10 +46,8 @@ public class AnimationLayerSet extends AnimatorListenerAdapter {

    @Override
    public void onAnimationEnd(Animator animation) {
        Iterator<Map.Entry<View, Integer>> itr = mViewsToLayerTypeMap.entrySet().iterator();
        while (itr.hasNext()) {
            Map.Entry<View, Integer> entry = itr.next();
            entry.getKey().setLayerType(entry.getValue(), null);
        for (View v : mViews) {
            v.setLayerType(View.LAYER_TYPE_NONE, null);
        }
    }
}