diff options
| author | TreeHugger Robot <treehugger-gerrit@google.com> | 2020-06-20 17:06:09 +0000 |
|---|---|---|
| committer | Android (Google) Code Review <android-gerrit@google.com> | 2020-06-20 17:06:09 +0000 |
| commit | cc498f3e695a18879b1e6cbb6ca348f654d1cf01 (patch) | |
| tree | aa65bc7330ee764fc6e97b574bde511c59811b4f /core/java | |
| parent | 3ed037cb4094e1fe287df7e7fc02808d946bf59f (diff) | |
| parent | 4291410118852cd6de6e4ce89a907fed1c33f92f (diff) | |
Merge "Animate IME with zero insets" into rvc-dev
Diffstat (limited to 'core/java')
5 files changed, 61 insertions, 13 deletions
diff --git a/core/java/android/view/InsetsAnimationControlImpl.java b/core/java/android/view/InsetsAnimationControlImpl.java index cd56ca9251ab..baeae2fd2cdd 100644 --- a/core/java/android/view/InsetsAnimationControlImpl.java +++ b/core/java/android/view/InsetsAnimationControlImpl.java @@ -16,13 +16,14 @@ package android.view; +import static android.view.InsetsController.ANIMATION_TYPE_SHOW; import static android.view.InsetsController.AnimationType; import static android.view.InsetsController.DEBUG; import static android.view.InsetsState.ISIDE_BOTTOM; -import static android.view.InsetsState.ISIDE_FLOATING; import static android.view.InsetsState.ISIDE_LEFT; import static android.view.InsetsState.ISIDE_RIGHT; import static android.view.InsetsState.ISIDE_TOP; +import static android.view.InsetsState.ITYPE_IME; import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE; @@ -74,6 +75,8 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll private final @InsetsType int mTypes; private final InsetsAnimationControlCallbacks mController; private final WindowInsetsAnimation mAnimation; + /** @see WindowInsetsAnimationController#hasZeroInsetsIme */ + private final boolean mHasZeroInsetsIme; private Insets mCurrentInsets; private Insets mPendingInsets; private float mPendingFraction; @@ -102,6 +105,12 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll null /* typeSideMap */); mShownInsets = calculateInsets(mInitialInsetsState, frame, controls, true /* shown */, mTypeSideMap); + mHasZeroInsetsIme = mShownInsets.bottom == 0 && controlsInternalType(ITYPE_IME); + if (mHasZeroInsetsIme) { + // IME has shownInsets of ZERO, and can't map to a side by default. + // Map zero insets IME to bottom, making it a special case of bottom insets. + mTypeSideMap.put(ITYPE_IME, ISIDE_BOTTOM); + } buildTypeSourcesMap(mTypeSideMap, mSideSourceMap, mControls); mAnimation = new WindowInsetsAnimation(mTypes, interpolator, @@ -113,6 +122,11 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll } @Override + public boolean hasZeroInsetsIme() { + return mHasZeroInsetsIme; + } + + @Override public Insets getHiddenStateInsets() { return mHiddenInsets; } @@ -182,8 +196,6 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll params, state, mPendingAlpha); updateLeashesForSide(ISIDE_BOTTOM, offset.bottom, mShownInsets.bottom, mPendingInsets.bottom, params, state, mPendingAlpha); - updateLeashesForSide(ISIDE_FLOATING, 0 /* offset */, 0 /* inset */, 0 /* maxInset */, - params, state, mPendingAlpha); mController.applySurfaceParams(params.toArray(new SurfaceParams[params.size()])); mCurrentInsets = mPendingInsets; @@ -290,6 +302,9 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll if (insets == null) { insets = getCurrentInsets(); } + if (hasZeroInsetsIme()) { + return insets; + } return Insets.max(Insets.min(insets, mShownInsets), mHiddenInsets); } @@ -313,17 +328,19 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll mTmpFrame.set(source.getFrame()); addTranslationToMatrix(side, offset, mTmpMatrix, mTmpFrame); - state.getSource(source.getType()).setVisible(side == ISIDE_FLOATING || inset != 0); + final boolean visible = mHasZeroInsetsIme && side == ISIDE_BOTTOM + ? (mAnimationType == ANIMATION_TYPE_SHOW ? true : !mFinished) + : inset != 0; + + state.getSource(source.getType()).setVisible(visible); state.getSource(source.getType()).setFrame(mTmpFrame); // If the system is controlling the insets source, the leash can be null. if (leash != null) { SurfaceParams params = new SurfaceParams.Builder(leash) - .withAlpha(side == ISIDE_FLOATING ? 1 : alpha) + .withAlpha(alpha) .withMatrix(mTmpMatrix) - .withVisibility(side == ISIDE_FLOATING - ? mShownOnFinish - : inset != 0 /* visible */) + .withVisibility(visible) .build(); surfaceParams.add(params); } diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java index dd48d554f296..5f99bfe432a4 100644 --- a/core/java/android/view/InsetsController.java +++ b/core/java/android/view/InsetsController.java @@ -162,6 +162,9 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation */ @Nullable String getRootViewTitle(); + + /** @see ViewRootImpl#dipToPx */ + int dipToPx(int dips); } private static final String TAG = "InsetsController"; @@ -254,6 +257,9 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation public static class InternalAnimationControlListener implements WindowInsetsAnimationControlListener { + /** The amount IME will move up/down when animating in floating mode. */ + protected static final int FLOATING_IME_BOTTOM_INSET = -80; + private WindowInsetsAnimationController mController; private ValueAnimator mAnimator; private final boolean mShow; @@ -261,6 +267,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation private final @InsetsType int mRequestedTypes; private final long mDurationMs; private final boolean mDisable; + private final int mFloatingImeBottomInset; private ThreadLocal<AnimationHandler> mSfAnimationHandlerThreadLocal = new ThreadLocal<AnimationHandler>() { @@ -273,12 +280,13 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation }; public InternalAnimationControlListener(boolean show, boolean hasAnimationCallbacks, - int requestedTypes, boolean disable) { + int requestedTypes, boolean disable, int floatingImeBottomInset) { mShow = show; mHasAnimationCallbacks = hasAnimationCallbacks; mRequestedTypes = requestedTypes; mDurationMs = calculateDurationMs(); mDisable = disable; + mFloatingImeBottomInset = floatingImeBottomInset; } @Override @@ -293,12 +301,19 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation mAnimator = ValueAnimator.ofFloat(0f, 1f); mAnimator.setDuration(mDurationMs); mAnimator.setInterpolator(new LinearInterpolator()); + Insets hiddenInsets = controller.getHiddenStateInsets(); + // IME with zero insets is a special case: it will animate-in from offscreen and end + // with final insets of zero and vice-versa. + hiddenInsets = controller.hasZeroInsetsIme() + ? Insets.of(hiddenInsets.left, hiddenInsets.top, hiddenInsets.right, + mFloatingImeBottomInset) + : hiddenInsets; Insets start = mShow - ? controller.getHiddenStateInsets() + ? hiddenInsets : controller.getShownStateInsets(); Insets end = mShow ? controller.getShownStateInsets() - : controller.getHiddenStateInsets(); + : hiddenInsets; Interpolator insetsInterpolator = getInterpolator(); Interpolator alphaInterpolator = getAlphaInterpolator(); mAnimator.addUpdateListener(animation -> { @@ -1173,7 +1188,8 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation boolean hasAnimationCallbacks = mHost.hasAnimationCallbacks(); final InternalAnimationControlListener listener = new InternalAnimationControlListener( - show, hasAnimationCallbacks, types, mAnimationsDisabled); + show, hasAnimationCallbacks, types, mAnimationsDisabled, + mHost.dipToPx(InternalAnimationControlListener.FLOATING_IME_BOTTOM_INSET)); // Show/hide animations always need to be relative to the display frame, in order that shown // and hidden state insets are correct. diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 2743654695e0..ed40483be337 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -2315,7 +2315,7 @@ public final class ViewRootImpl implements ViewParent, || lp.type == TYPE_VOLUME_OVERLAY; } - private int dipToPx(int dip) { + int dipToPx(int dip) { final DisplayMetrics displayMetrics = mContext.getResources().getDisplayMetrics(); return (int) (displayMetrics.density * dip + 0.5f); } diff --git a/core/java/android/view/ViewRootInsetsControllerHost.java b/core/java/android/view/ViewRootInsetsControllerHost.java index 31a44023b036..f7ca3c2b7ddf 100644 --- a/core/java/android/view/ViewRootInsetsControllerHost.java +++ b/core/java/android/view/ViewRootInsetsControllerHost.java @@ -228,4 +228,12 @@ public class ViewRootInsetsControllerHost implements InsetsController.Host { } return mViewRoot.getTitle().toString(); } + + @Override + public int dipToPx(int dips) { + if (mViewRoot != null) { + return mViewRoot.dipToPx(dips); + } + return 0; + } } diff --git a/core/java/android/view/WindowInsetsAnimationController.java b/core/java/android/view/WindowInsetsAnimationController.java index fb9d05e2d730..792b974558bb 100644 --- a/core/java/android/view/WindowInsetsAnimationController.java +++ b/core/java/android/view/WindowInsetsAnimationController.java @@ -181,4 +181,11 @@ public interface WindowInsetsAnimationController { * @return {@code true} if the instance is cancelled, {@code false} otherwise. */ boolean isCancelled(); + + /** + * @hide + * @return {@code true} when controller controls IME and IME has no insets (floating, + * fullscreen or non-overlapping). + */ + boolean hasZeroInsetsIme(); } |
