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

Commit 45a1c3a1 authored by Fabian Kozynski's avatar Fabian Kozynski
Browse files

Animate appearing tiles in QS

The appearing tiles get expanded from 0 to the final height. Their top
moves following the other expanding tiles so it looks like they come
from a coherent surface.

Test: manual
Bug: 181673785
Change-Id: Ib4492190b53afccd8c3071070d7adf29eb1ed6ed
parent 73d252fd
Loading
Loading
Loading
Loading
+66 −32
Original line number Original line Diff line number Diff line
@@ -80,7 +80,8 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha
    // This animates fading of SecurityFooter and media divider
    // This animates fading of SecurityFooter and media divider
    private TouchAnimator mAllPagesDelayedAnimator;
    private TouchAnimator mAllPagesDelayedAnimator;
    private TouchAnimator mBrightnessAnimator;
    private TouchAnimator mBrightnessAnimator;
    private QQSTileAnimator mQQSTileAnimator;
    private HeightExpansionAnimator mQQSTileHeightAnimator;
    private HeightExpansionAnimator mOtherTilesExpandAnimator;


    private boolean mNeedsAnimatorUpdate = false;
    private boolean mNeedsAnimatorUpdate = false;


@@ -166,7 +167,7 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha
    @Override
    @Override
    public void onViewAttachedToWindow(View v) {
    public void onViewAttachedToWindow(View v) {
        mTunerService.addTunable(this, ALLOW_FANCY_ANIMATION,
        mTunerService.addTunable(this, ALLOW_FANCY_ANIMATION,
                MOVE_FULL_ROWS, QuickQSPanel.NUM_QUICK_TILES);
                MOVE_FULL_ROWS);
    }
    }


    @Override
    @Override
@@ -184,9 +185,6 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha
            }
            }
        } else if (MOVE_FULL_ROWS.equals(key)) {
        } else if (MOVE_FULL_ROWS.equals(key)) {
            mFullRows = TunerService.parseIntegerSwitch(newValue, true);
            mFullRows = TunerService.parseIntegerSwitch(newValue, true);
        } else if (QuickQSPanel.NUM_QUICK_TILES.equals(key)) {
            mNumQuickTiles = QuickQSPanel.parseNumTiles(newValue);
            clearAnimationState();
        }
        }
        updateAnimators();
        updateAnimators();
    }
    }
@@ -214,7 +212,10 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha
        clearAnimationState();
        clearAnimationState();
        mAllViews.clear();
        mAllViews.clear();
        mQuickQsViews.clear();
        mQuickQsViews.clear();
        mQQSTileAnimator = null;
        mQQSTileHeightAnimator = null;
        mOtherTilesExpandAnimator = null;

        mNumQuickTiles = mQuickQsPanel.getNumQuickTiles();


        QSTileLayout tileLayout = mQsPanelController.getTileLayout();
        QSTileLayout tileLayout = mQsPanelController.getTileLayout();
        mAllViews.add((View) tileLayout);
        mAllViews.add((View) tileLayout);
@@ -225,6 +226,7 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha
        firstPageBuilder.addFloat(tileLayout, "translationY", heightDiff, 0);
        firstPageBuilder.addFloat(tileLayout, "translationY", heightDiff, 0);


        boolean qsSideLabelsEnabled = mFeatureFlags.isQSLabelsEnabled();
        boolean qsSideLabelsEnabled = mFeatureFlags.isQSLabelsEnabled();
        int qqsTileHeight = 0;


        for (QSTile tile : tiles) {
        for (QSTile tile : tiles) {
            QSTileView tileView = mQsPanelController.getTileView(tile);
            QSTileView tileView = mQsPanelController.getTileView(tile);
@@ -267,13 +269,13 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha
                        translationYBuilder.addFloat(quickTileView, "translationY", 0, yOffset);
                        translationYBuilder.addFloat(quickTileView, "translationY", 0, yOffset);
                        translationYBuilder.addFloat(tileView, "translationY", -yOffset, 0);
                        translationYBuilder.addFloat(tileView, "translationY", -yOffset, 0);


                        if (mQQSTileAnimator == null) {
                        if (mQQSTileHeightAnimator == null) {
                            mQQSTileAnimator = new QQSTileAnimator(this);
                            mQQSTileHeightAnimator = new HeightExpansionAnimator(this,
                            mQQSTileAnimator.setHeights(quickTileView.getHeight(),
                                    quickTileView.getHeight(), tileView.getHeight());
                                    tileView.getHeight());
                            qqsTileHeight = quickTileView.getHeight();
                        }
                        }


                        mQQSTileAnimator.addView(quickTileView);
                        mQQSTileHeightAnimator.addView(quickTileView);
                        View qqsLabelContainer = quickTileView.getLabelContainer();
                        View qqsLabelContainer = quickTileView.getLabelContainer();
                        View qsLabelContainer = tileView.getLabelContainer();
                        View qsLabelContainer = tileView.getLabelContainer();


@@ -311,8 +313,27 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha


                mAllViews.add(tileIcon);
                mAllViews.add(tileIcon);
            } else {
            } else {
                if (!qsSideLabelsEnabled) {
                    firstPageBuilder.addFloat(tileView, "alpha", 0, 1);
                    firstPageBuilder.addFloat(tileView, "alpha", 0, 1);
                    firstPageBuilder.addFloat(tileView, "translationY", -heightDiff, 0);
                    firstPageBuilder.addFloat(tileView, "translationY", -heightDiff, 0);
                } else {
                    // Pretend there's a corresponding QQS tile (for the position) that we are
                    // expanding from.
                    SideLabelTileLayout qqsLayout =
                            (SideLabelTileLayout) mQuickQsPanel.getTileLayout();
                    getRelativePosition(loc1, qqsLayout, view);
                    getRelativePosition(loc2, tileView, view);
                    int diff = loc2[1] - (loc1[1] + qqsLayout.getPhantomTopPosition(count));
                    translationYBuilder.addFloat(tileView, "translationY", -diff, 0);
                    if (mOtherTilesExpandAnimator == null) {
                        mOtherTilesExpandAnimator =
                                new HeightExpansionAnimator(
                                        this, qqsTileHeight, tileView.getHeight());
                    }
                    mOtherTilesExpandAnimator.addView(tileView);
                    tileView.setClipChildren(true);
                    tileView.setClipToPadding(true);
                }
            }
            }


            mAllViews.add(tileView);
            mAllViews.add(tileView);
@@ -337,7 +358,7 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha
                    .build();
                    .build();
            // Fade in the tiles/labels as we reach the final position.
            // Fade in the tiles/labels as we reach the final position.
            Builder builder = new Builder()
            Builder builder = new Builder()
                    .setStartDelay(EXPANDED_TILE_DELAY)
                    .setStartDelay(qsSideLabelsEnabled ? 0 : EXPANDED_TILE_DELAY)
                    .addFloat(tileLayout, "alpha", 0, 1);
                    .addFloat(tileLayout, "alpha", 0, 1);
            mFirstPageDelayedAnimator = builder.build();
            mFirstPageDelayedAnimator = builder.build();


@@ -365,8 +386,11 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha
            translationYBuilder.setInterpolator(interpolatorBuilder.getYInterpolator());
            translationYBuilder.setInterpolator(interpolatorBuilder.getYInterpolator());
            mTranslationXAnimator = translationXBuilder.build();
            mTranslationXAnimator = translationXBuilder.build();
            mTranslationYAnimator = translationYBuilder.build();
            mTranslationYAnimator = translationYBuilder.build();
            if (mQQSTileAnimator != null) {
            if (mQQSTileHeightAnimator != null) {
                mQQSTileAnimator.setInterpolator(interpolatorBuilder.getYInterpolator());
                mQQSTileHeightAnimator.setInterpolator(interpolatorBuilder.getYInterpolator());
            }
            if (mOtherTilesExpandAnimator != null) {
                mOtherTilesExpandAnimator.setInterpolator(interpolatorBuilder.getYInterpolator());
            }
            }
        }
        }
        mNonfirstPageAnimator = new TouchAnimator.Builder()
        mNonfirstPageAnimator = new TouchAnimator.Builder()
@@ -441,8 +465,11 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha
            if (mBrightnessAnimator != null) {
            if (mBrightnessAnimator != null) {
                mBrightnessAnimator.setPosition(position);
                mBrightnessAnimator.setPosition(position);
            }
            }
            if (mQQSTileAnimator != null) {
            if (mQQSTileHeightAnimator != null) {
                mQQSTileAnimator.setPosition(position);
                mQQSTileHeightAnimator.setPosition(position);
            }
            if (mOtherTilesExpandAnimator != null) {
                mOtherTilesExpandAnimator.setPosition(position);
            }
            }
        } else {
        } else {
            mNonfirstPageAnimator.setPosition(position);
            mNonfirstPageAnimator.setPosition(position);
@@ -486,11 +513,16 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha
            v.setAlpha(1);
            v.setAlpha(1);
            v.setTranslationX(0);
            v.setTranslationX(0);
            v.setTranslationY(0);
            v.setTranslationY(0);
            if (v instanceof SideLabelTileLayout) {
                ((SideLabelTileLayout) v).setClipChildren(false);
                ((SideLabelTileLayout) v).setClipToPadding(false);
            }
            }
        if (mQQSTileAnimator != null) {
            for (View v : mQQSTileAnimator.getViews()) {
                v.setBottom(v.getTop() + v.getMeasuredHeight());
        }
        }
        if (mQQSTileHeightAnimator != null) {
            mQQSTileHeightAnimator.resetViewsHeights();
        }
        if (mOtherTilesExpandAnimator != null) {
            mOtherTilesExpandAnimator.resetViewsHeights();
        }
        }
        final int N2 = mQuickQsViews.size();
        final int N2 = mQuickQsViews.size();
        for (int i = 0; i < N2; i++) {
        for (int i = 0; i < N2; i++) {
@@ -529,7 +561,7 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha
        setCurrentPosition();
        setCurrentPosition();
    };
    };


    static class QQSTileAnimator {
    static class HeightExpansionAnimator {
        private final List<View> mViews = new ArrayList<>();
        private final List<View> mViews = new ArrayList<>();
        private final ValueAnimator mAnimator;
        private final ValueAnimator mAnimator;
        private final TouchAnimator.Listener mListener;
        private final TouchAnimator.Listener mListener;
@@ -548,16 +580,18 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha
                    mListener.onAnimationStarted();
                    mListener.onAnimationStarted();
                }
                }
                mLastT = t;
                mLastT = t;
                final int viewCount = mViews.size();
                int height = (Integer) valueAnimator.getAnimatedValue();
                int height = (Integer) valueAnimator.getAnimatedValue();
                for (View v : mViews) {
                for (int i = 0; i < viewCount; i++) {
                    View v = mViews.get(i);
                    v.setBottom(v.getTop() + height);
                    v.setBottom(v.getTop() + height);
                }
                }
            }
            }
        };
        };


        QQSTileAnimator(TouchAnimator.Listener listener) {
        HeightExpansionAnimator(TouchAnimator.Listener listener, int startHeight, int endHeight) {
            mListener = listener;
            mListener = listener;
            mAnimator = ValueAnimator.ofInt(0, 0);
            mAnimator = ValueAnimator.ofInt(startHeight, endHeight);
            mAnimator.setRepeatCount(ValueAnimator.INFINITE);
            mAnimator.setRepeatCount(ValueAnimator.INFINITE);
            mAnimator.setRepeatMode(ValueAnimator.REVERSE);
            mAnimator.setRepeatMode(ValueAnimator.REVERSE);
            mAnimator.addUpdateListener(mUpdateListener);
            mAnimator.addUpdateListener(mUpdateListener);
@@ -567,10 +601,6 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha
            mViews.add(v);
            mViews.add(v);
        }
        }


        void setHeights(int startHeight, int endHeight) {
            mAnimator.setIntValues(startHeight, endHeight);
        }

        void setInterpolator(TimeInterpolator interpolator) {
        void setInterpolator(TimeInterpolator interpolator) {
            mAnimator.setInterpolator(interpolator);
            mAnimator.setInterpolator(interpolator);
        }
        }
@@ -579,8 +609,12 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha
            mAnimator.setCurrentFraction(position);
            mAnimator.setCurrentFraction(position);
        }
        }


        List<View> getViews() {
        void resetViewsHeights() {
            return mViews;
            final int viewsCount = mViews.size();
            for (int i = 0; i < viewsCount; i++) {
                View v = mViews.get(i);
                v.setBottom(v.getTop() + v.getMeasuredHeight());
            }
        }
        }
    }
    }
}
}
+11 −0
Original line number Original line Diff line number Diff line
@@ -33,4 +33,15 @@ open class SideLabelTileLayout(
    override fun isFull(): Boolean {
    override fun isFull(): Boolean {
        return mRecords.size >= maxTiles()
        return mRecords.size >= maxTiles()
    }
    }

    /**
     * Return the position from the top of the layout of the tile with this index.
     *
     * This will return a position even for indices that go beyond [maxTiles], continuing the rows
     * beyond that.
     */
    fun getPhantomTopPosition(index: Int): Int {
        val row = index / mColumns
        return getRowTop(row)
    }
}
}
 No newline at end of file
+1 −1
Original line number Original line Diff line number Diff line
@@ -236,7 +236,7 @@ public class TileLayout extends ViewGroup implements QSTileLayout {
        layoutTileRecords(mRecords.size());
        layoutTileRecords(mRecords.size());
    }
    }


    private int getRowTop(int row) {
    protected int getRowTop(int row) {
        return row * (mCellHeight + mCellMarginVertical) + mCellMarginTop;
        return row * (mCellHeight + mCellMarginVertical) + mCellMarginTop;
    }
    }