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

Commit 317effcd authored by Selim Cinek's avatar Selim Cinek
Browse files

Improved Text transformations for notifications

Notifications with different text sizes can now properly transform
into each other using view scaling. This improves the transition
for min priority notifications.

Test: manual, expand min priority notification, observe smooth transformation
Change-Id: Icc8efa8521e6a5346607f0ca330e1bc519dbb345
Fixes: 38397448
parent d43bc31e
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -116,7 +116,7 @@ public class ImageTransformState extends TransformState {
    }

    @Override
    protected boolean transformScale() {
    protected boolean transformScale(TransformState otherState) {
        return true;
    }

+59 −1
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.systemui.statusbar.notification;

import android.text.Layout;
import android.text.Spanned;
import android.text.TextUtils;
import android.util.Pools;
import android.view.View;
@@ -50,12 +51,69 @@ public class TextViewTransformState extends TransformState {
                int ownEllipsized = getEllipsisCount();
                int otherEllipsized = otherTvs.getEllipsisCount();
                return ownEllipsized == otherEllipsized
                        && getInnerHeight(mText) == getInnerHeight(otherTvs.mText);
                        && mText.getLineCount() == otherTvs.mText.getLineCount()
                        && hasSameSpans(otherTvs);
            }
        }
        return false;
    }

    private boolean hasSameSpans(TextViewTransformState otherTvs) {
        boolean hasSpans = mText instanceof Spanned;
        boolean otherHasSpans = otherTvs.mText instanceof Spanned;
        if (hasSpans != otherHasSpans) {
            return false;
        } else if (!hasSpans) {
            return true;
        }
        // Actually both have spans, let's try to compare them
        Spanned ownSpanned = (Spanned) mText;
        Object[] spans = ownSpanned.getSpans(0, ownSpanned.length(), Object.class);
        Spanned otherSpanned = (Spanned) otherTvs.mText;
        Object[] otherSpans = otherSpanned.getSpans(0, otherSpanned.length(), Object.class);
        if (spans.length != otherSpans.length) {
            return false;
        }
        for (int i = 0; i < spans.length; i++) {
            Object span = spans[i];
            Object otherSpan = otherSpans[i];
            if (!span.getClass().equals(otherSpan.getClass())) {
                return false;
            }
            if (ownSpanned.getSpanStart(span) != otherSpanned.getSpanStart(otherSpan)
                    || ownSpanned.getSpanEnd(span) != otherSpanned.getSpanEnd(otherSpan)) {
                return false;
            }
        }
        return true;
    }

    @Override
    protected boolean transformScale(TransformState otherState) {
        if (!(otherState instanceof TextViewTransformState)) {
            return false;
        }
        TextViewTransformState otherTvs = (TextViewTransformState) otherState;
        int lineCount = mText.getLineCount();
        return lineCount == 1 && lineCount == otherTvs.mText.getLineCount()
                && getEllipsisCount() == otherTvs.getEllipsisCount()
                && getViewHeight() != otherTvs.getViewHeight();
    }

    @Override
    protected int getViewWidth() {
        Layout l = mText.getLayout();
        if (l != null) {
            return (int) l.getLineWidth(0);
        }
        return super.getViewWidth();
    }

    @Override
    protected int getViewHeight() {
        return mText.getLineHeight();
    }

    private int getInnerHeight(TextView text) {
        return text.getHeight() - text.getPaddingTop() - text.getPaddingBottom();
    }
+21 −13
Original line number Diff line number Diff line
@@ -108,7 +108,7 @@ public class TransformState {
        final View transformedView = mTransformedView;
        boolean transformX = (transformationFlags & TRANSFORM_X) != 0;
        boolean transformY = (transformationFlags & TRANSFORM_Y) != 0;
        boolean transformScale = transformScale();
        boolean transformScale = transformScale(otherState);
        // lets animate the positions correctly
        if (transformationAmount == 0.0f
                || transformX && getTransformationStartX() == UNDEFINED
@@ -132,16 +132,16 @@ public class TransformState {
                }
                // we also want to animate the scale if we're the same
                View otherView = otherState.getTransformedView();
                if (transformScale && otherView.getWidth() != transformedView.getWidth()) {
                    setTransformationStartScaleX(otherView.getWidth() * otherView.getScaleX()
                            / (float) transformedView.getWidth());
                if (transformScale && otherState.getViewWidth() != getViewWidth()) {
                    setTransformationStartScaleX(otherState.getViewWidth() * otherView.getScaleX()
                            / (float) getViewWidth());
                    transformedView.setPivotX(0);
                } else {
                    setTransformationStartScaleX(UNDEFINED);
                }
                if (transformScale && otherView.getHeight() != transformedView.getHeight()) {
                    setTransformationStartScaleY(otherView.getHeight() * otherView.getScaleY()
                            / (float) transformedView.getHeight());
                if (transformScale && otherState.getViewHeight() != getViewHeight()) {
                    setTransformationStartScaleY(otherState.getViewHeight() * otherView.getScaleY()
                            / (float) getViewHeight());
                    transformedView.setPivotY(0);
                } else {
                    setTransformationStartScaleY(UNDEFINED);
@@ -205,7 +205,15 @@ public class TransformState {
        }
    }

    protected boolean transformScale() {
    protected int getViewWidth() {
        return mTransformedView.getWidth();
    }

    protected int getViewHeight() {
        return mTransformedView.getHeight();
    }

    protected boolean transformScale(TransformState otherState) {
        return false;
    }

@@ -259,7 +267,7 @@ public class TransformState {
        final View transformedView = mTransformedView;
        boolean transformX = (transformationFlags & TRANSFORM_X) != 0;
        boolean transformY = (transformationFlags & TRANSFORM_Y) != 0;
        boolean transformScale = transformScale();
        boolean transformScale = transformScale(otherState);
        // lets animate the positions correctly
        if (transformationAmount == 0.0f) {
            if (transformX) {
@@ -275,13 +283,13 @@ public class TransformState {
                setTransformationStartY(start);
            }
            View otherView = otherState.getTransformedView();
            if (transformScale && otherView.getWidth() != transformedView.getWidth()) {
            if (transformScale && otherState.getViewWidth() != getViewWidth()) {
                setTransformationStartScaleX(transformedView.getScaleX());
                transformedView.setPivotX(0);
            } else {
                setTransformationStartScaleX(UNDEFINED);
            }
            if (transformScale && otherView.getHeight() != transformedView.getHeight()) {
            if (transformScale && otherState.getViewHeight() != getViewHeight()) {
                setTransformationStartScaleY(transformedView.getScaleY());
                transformedView.setPivotY(0);
            } else {
@@ -333,14 +341,14 @@ public class TransformState {
            if (transformationStartScaleX != UNDEFINED) {
                transformedView.setScaleX(
                        NotificationUtils.interpolate(transformationStartScaleX,
                                (otherView.getWidth() / (float) transformedView.getWidth()),
                                (otherState.getViewWidth() / (float) getViewWidth()),
                                interpolatedValue));
            }
            float transformationStartScaleY = getTransformationStartScaleY();
            if (transformationStartScaleY != UNDEFINED) {
                transformedView.setScaleY(
                        NotificationUtils.interpolate(transformationStartScaleY,
                                (otherView.getHeight() / (float) transformedView.getHeight()),
                                (otherState.getViewHeight() / (float) getViewHeight()),
                                interpolatedValue));
            }
        }