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

Commit 36e39974 authored by Doris Liu's avatar Doris Liu Committed by Android (Google) Code Review
Browse files

Merge "Set a HW layer for Fragment alpha animation" into mnc-dev

parents 44aef99a de9284de
Loading
Loading
Loading
Loading
+89 −0
Original line number Diff line number Diff line
@@ -19,6 +19,9 @@ package android.app;
import android.animation.Animator;
import android.animation.AnimatorInflater;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.PropertyValuesHolder;
import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.TypedArray;
@@ -403,6 +406,44 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate
    static final String VIEW_STATE_TAG = "android:view_state";
    static final String USER_VISIBLE_HINT_TAG = "android:user_visible_hint";

    static class AnimateOnHWLayerIfNeededListener implements Animator.AnimatorListener {
        private boolean mShouldRunOnHWLayer = false;
        private View mView;
        public AnimateOnHWLayerIfNeededListener(final View v) {
            if (v == null) {
                return;
            }
            mView = v;
        }

        @Override
        public void onAnimationStart(Animator animation) {
            mShouldRunOnHWLayer = shouldRunOnHWLayer(mView, animation);
            if (mShouldRunOnHWLayer) {
                mView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
            }
        }

        @Override
        public void onAnimationEnd(Animator animation) {
            if (mShouldRunOnHWLayer) {
                mView.setLayerType(View.LAYER_TYPE_NONE, null);
            }
            mView = null;
            animation.removeListener(this);
        }

        @Override
        public void onAnimationCancel(Animator animation) {

        }

        @Override
        public void onAnimationRepeat(Animator animation) {

        }
    }

    ArrayList<Runnable> mPendingActions;
    Runnable[] mTmpActions;
    boolean mExecutingActions;
@@ -467,6 +508,50 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate
        throw ex;
    }

    static boolean modifiesAlpha(Animator anim) {
        if (anim == null) {
            return false;
        }
        if (anim instanceof ValueAnimator) {
            ValueAnimator valueAnim = (ValueAnimator) anim;
            PropertyValuesHolder[] values = valueAnim.getValues();
            for (int i = 0; i < values.length; i++) {
                if (("alpha").equals(values[i].getPropertyName())) {
                    return true;
                }
            }
        } else if (anim instanceof AnimatorSet) {
            List<Animator> animList = ((AnimatorSet) anim).getChildAnimations();
            for (int i = 0; i < animList.size(); i++) {
                if (modifiesAlpha(animList.get(i))) {
                    return true;
                }
            }
        }
        return false;
    }

    static boolean shouldRunOnHWLayer(View v, Animator anim) {
        if (v == null || anim == null) {
            return false;
        }
        return v.getLayerType() == View.LAYER_TYPE_NONE
                && v.hasOverlappingRendering()
                && modifiesAlpha(anim);
    }

    /**
     * Sets the to be animated view on hardware layer during the animation.
     */
    private void setHWLayerAnimListenerIfAlpha(final View v, Animator anim) {
        if (v == null || anim == null) {
            return;
        }
        if (shouldRunOnHWLayer(v, anim)) {
            anim.addListener(new AnimateOnHWLayerIfNeededListener(v));
        }
    }

    @Override
    public FragmentTransaction beginTransaction() {
        return new BackStackRecord(this);
@@ -894,6 +979,7 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate
                                            transitionStyle);
                                    if (anim != null) {
                                        anim.setTarget(f.mView);
                                        setHWLayerAnimListenerIfAlpha(f.mView, anim);
                                        anim.start();
                                    }
                                    container.addView(f.mView);
@@ -975,6 +1061,7 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate
                                    }
                                });
                                anim.setTarget(f.mView);
                                setHWLayerAnimListenerIfAlpha(f.mView, anim);
                                anim.start();

                            }
@@ -1188,6 +1275,7 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate
                            }
                        }
                    });
                    setHWLayerAnimListenerIfAlpha(finalFragment.mView, anim);
                    anim.start();
                } else {
                    fragment.mView.setVisibility(View.GONE);
@@ -1209,6 +1297,7 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate
                        transitionStyle);
                if (anim != null) {
                    anim.setTarget(fragment.mView);
                    setHWLayerAnimListenerIfAlpha(fragment.mView, anim);
                    anim.start();
                }
                fragment.mView.setVisibility(View.VISIBLE);