Merge "Add folder UI animation." into ub-launcher3-master
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index cacd3fb..2e36bc0 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -88,6 +88,7 @@
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 @@
mUserChangedCallbackCloseable = UserCache.INSTANCE.get(this).addUserChangeListener(
() -> getStateManager().goToState(NORMAL));
+
+ if (Utilities.ATLEAST_R) {
+ getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING);
+ }
}
protected LauncherOverlayManager getDefaultOverlay() {
diff --git a/src/com/android/launcher3/folder/Folder.java b/src/com/android/launcher3/folder/Folder.java
index f1606ea..c841b7b 100644
--- a/src/com/android/launcher3/folder/Folder.java
+++ b/src/com/android/launcher3/folder/Folder.java
@@ -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.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.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 @@
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 @@
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 @@
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;
+ }
+
+ }
}