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
This commit is contained in:
@@ -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() {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user