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

Commit 8a35c764 authored by Schneider Victor-tulias's avatar Schneider Victor-tulias
Browse files

Add folder UI animation.

Test: manual

Fixing b/144948355. The entire launcher was panning up when the user
would try to edit a folder name if that folder's name field would have
otherwise been obscured by the keyboard. This had the effect of
obscuring the smartspace. Added an animation to the folder UI to bring
it above the keyboard during text editing.

Change-Id: I0f95aae27fc7426f1025135ea6d4fa142a21cf43
parent 1aee9da5
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -88,6 +88,7 @@ import android.view.Menu;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityEvent;
import android.view.animation.OvershootInterpolator;
import android.widget.Toast;
@@ -466,6 +467,10 @@ public class Launcher extends StatefulActivity<LauncherState> implements Launche

        mUserChangedCallbackCloseable = UserCache.INSTANCE.get(this).addUserChangeListener(
                () -> getStateManager().goToState(NORMAL));

        if (Utilities.ATLEAST_R) {
            getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING);
        }
    }

    protected LauncherOverlayManager getDefaultOverlay() {
+95 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.launcher3.folder;

import static android.text.TextUtils.isEmpty;
import static android.view.WindowInsetsAnimation.Callback.DISPATCH_MODE_STOP;

import static com.android.launcher3.LauncherAnimUtils.SPRING_LOADED_EXIT_DELAY;
import static com.android.launcher3.LauncherState.NORMAL;
@@ -34,8 +35,10 @@ import android.annotation.SuppressLint;
import android.appwidget.AppWidgetHostView;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Insets;
import android.graphics.Path;
import android.graphics.Rect;
import android.os.Build;
import android.text.InputType;
import android.text.Selection;
import android.text.TextUtils;
@@ -47,11 +50,16 @@ import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewDebug;
import android.view.WindowInsets;
import android.view.WindowInsetsAnimation;
import android.view.accessibility.AccessibilityEvent;
import android.view.animation.AnimationUtils;
import android.view.inputmethod.EditorInfo;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;

import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.Alarm;
import com.android.launcher3.BubbleTextView;
@@ -252,6 +260,13 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo
        int measureSpec = MeasureSpec.UNSPECIFIED;
        mFooter.measure(measureSpec, measureSpec);
        mFooterHeight = mFooter.getMeasuredHeight();

        if (Utilities.ATLEAST_R) {
            WindowInsetsAnimation.Callback cb = new FolderWindowInsetsAnimationCallback(
                    DISPATCH_MODE_STOP, this);

            setWindowInsetsAnimationCallback(cb);
        }
    }

    public boolean onLongClick(View v) {
@@ -373,6 +388,26 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo
        return false;
    }

    @Override
    public WindowInsets onApplyWindowInsets(WindowInsets windowInsets) {
        if (Utilities.ATLEAST_R) {
            this.setTranslationY(0);

            if (windowInsets.isVisible(WindowInsets.Type.ime())) {
                Insets keyboardInsets = windowInsets.getInsets(WindowInsets.Type.ime());
                int folderHeightFromBottom = getHeightFromBottom();

                if (keyboardInsets.bottom > folderHeightFromBottom) {
                    // Translate this folder above the keyboard, then add the folder name's padding
                    this.setTranslationY(folderHeightFromBottom - keyboardInsets.bottom
                            - mFolderName.getPaddingBottom());
                }
            }
        }

        return windowInsets;
    }

    public FolderIcon getFolderIcon() {
        return mFolderIcon;
    }
@@ -1646,4 +1681,64 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo
        mLauncher.getUserEventDispatcher()
                .logLauncherEvent(mInfo.getFolderLabelStateLauncherEvent(fromState, toState));
    }

    /** Returns the height of the current folder's bottom edge from the bottom of the screen. */
    private int getHeightFromBottom() {
        DragLayer.LayoutParams layoutParams = (DragLayer.LayoutParams) getLayoutParams();
        int folderBottomPx = layoutParams.y + layoutParams.height;
        int windowBottomPx = mLauncher.getDeviceProfile().heightPx;

        return windowBottomPx - folderBottomPx;
    }

    /** Callback that animates a folder sliding up above the ime. */
    @RequiresApi(api = Build.VERSION_CODES.R)
    private static class FolderWindowInsetsAnimationCallback
            extends WindowInsetsAnimation.Callback {

        private final Folder mFolder;
        float mFolderTranslationStart;
        float mFolderTranslationEnd;

        FolderWindowInsetsAnimationCallback(int dispatchMode, Folder folder) {
            super(dispatchMode);

            mFolder = folder;
        }

        @Override
        public void onPrepare(@NonNull WindowInsetsAnimation animation) {
            mFolderTranslationStart = mFolder.getTranslationY();
        }

        @NonNull
        @Override
        public WindowInsetsAnimation.Bounds onStart(
                @NonNull WindowInsetsAnimation animation,
                @NonNull WindowInsetsAnimation.Bounds bounds) {
            mFolderTranslationEnd = mFolder.getTranslationY();

            mFolder.setTranslationY(mFolderTranslationStart);

            return super.onStart(animation, bounds);
        }

        @NonNull
        @Override
        public WindowInsets onProgress(@NonNull WindowInsets windowInsets,
                @NonNull List<WindowInsetsAnimation> list) {
            if (list.size() == 0) {
                mFolder.setTranslationY(0);

                return windowInsets;
            }
            float progress = list.get(0).getInterpolatedFraction();

            mFolder.setTranslationY(
                    Utilities.mapRange(progress, mFolderTranslationStart, mFolderTranslationEnd));

            return windowInsets;
        }

    }
}