Merge "Reapply changes of inline reply CL" into tm-qpr-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
ccff5e1445
@@ -464,9 +464,6 @@ public class NotificationRemoteInputManager implements Dumpable {
|
|||||||
riv.getController().setRemoteInputs(inputs);
|
riv.getController().setRemoteInputs(inputs);
|
||||||
riv.getController().setEditedSuggestionInfo(editedSuggestionInfo);
|
riv.getController().setEditedSuggestionInfo(editedSuggestionInfo);
|
||||||
ViewGroup parent = view.getParent() != null ? (ViewGroup) view.getParent() : null;
|
ViewGroup parent = view.getParent() != null ? (ViewGroup) view.getParent() : null;
|
||||||
if (parent != null) {
|
|
||||||
riv.setDefocusTargetHeight(parent.getHeight());
|
|
||||||
}
|
|
||||||
riv.focusAnimated(parent);
|
riv.focusAnimated(parent);
|
||||||
if (userMessageContent != null) {
|
if (userMessageContent != null) {
|
||||||
riv.setEditTextContent(userMessageContent);
|
riv.setEditTextContent(userMessageContent);
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ import android.view.OnReceiveContentListener;
|
|||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewAnimationUtils;
|
import android.view.ViewAnimationUtils;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
import android.view.ViewGroupOverlay;
|
||||||
import android.view.ViewRootImpl;
|
import android.view.ViewRootImpl;
|
||||||
import android.view.WindowInsets;
|
import android.view.WindowInsets;
|
||||||
import android.view.WindowInsetsAnimation;
|
import android.view.WindowInsetsAnimation;
|
||||||
@@ -57,7 +58,6 @@ import android.view.inputmethod.EditorInfo;
|
|||||||
import android.view.inputmethod.InputConnection;
|
import android.view.inputmethod.InputConnection;
|
||||||
import android.view.inputmethod.InputMethodManager;
|
import android.view.inputmethod.InputMethodManager;
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
import android.widget.FrameLayout;
|
|
||||||
import android.widget.ImageButton;
|
import android.widget.ImageButton;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
@@ -133,6 +133,7 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene
|
|||||||
private RevealParams mRevealParams;
|
private RevealParams mRevealParams;
|
||||||
private Rect mContentBackgroundBounds;
|
private Rect mContentBackgroundBounds;
|
||||||
private boolean mIsFocusAnimationFlagActive;
|
private boolean mIsFocusAnimationFlagActive;
|
||||||
|
private boolean mIsAnimatingAppearance = false;
|
||||||
|
|
||||||
// TODO(b/193539698): move these to a Controller
|
// TODO(b/193539698): move these to a Controller
|
||||||
private RemoteInputController mController;
|
private RemoteInputController mController;
|
||||||
@@ -142,10 +143,6 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene
|
|||||||
private boolean mSending;
|
private boolean mSending;
|
||||||
private NotificationViewWrapper mWrapper;
|
private NotificationViewWrapper mWrapper;
|
||||||
|
|
||||||
private Integer mDefocusTargetHeight = null;
|
|
||||||
private boolean mIsAnimatingAppearance = false;
|
|
||||||
|
|
||||||
|
|
||||||
// TODO(b/193539698): remove this; views shouldn't have access to their controller, and places
|
// TODO(b/193539698): remove this; views shouldn't have access to their controller, and places
|
||||||
// that need the controller shouldn't have access to the view
|
// that need the controller shouldn't have access to the view
|
||||||
private RemoteInputViewController mViewController;
|
private RemoteInputViewController mViewController;
|
||||||
@@ -423,18 +420,6 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene
|
|||||||
return mIsAnimatingAppearance;
|
return mIsAnimatingAppearance;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* View will ensure to use at most the provided defocusTargetHeight, when defocusing animated.
|
|
||||||
* This is to ensure that the parent can resize itself to the targetHeight while the defocus
|
|
||||||
* animation of the RemoteInputView is running.
|
|
||||||
*
|
|
||||||
* @param defocusTargetHeight The target height the parent will resize itself to. If null, the
|
|
||||||
* RemoteInputView will not resize itself.
|
|
||||||
*/
|
|
||||||
public void setDefocusTargetHeight(Integer defocusTargetHeight) {
|
|
||||||
mDefocusTargetHeight = defocusTargetHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
void onDefocus(boolean animate, boolean logClose) {
|
void onDefocus(boolean animate, boolean logClose) {
|
||||||
mController.removeRemoteInput(mEntry, mToken);
|
mController.removeRemoteInput(mEntry, mToken);
|
||||||
@@ -443,35 +428,28 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene
|
|||||||
// During removal, we get reattached and lose focus. Not hiding in that
|
// During removal, we get reattached and lose focus. Not hiding in that
|
||||||
// case to prevent flicker.
|
// case to prevent flicker.
|
||||||
if (!mRemoved) {
|
if (!mRemoved) {
|
||||||
if (animate && mIsFocusAnimationFlagActive) {
|
ViewGroup parent = (ViewGroup) getParent();
|
||||||
Animator animator = getDefocusAnimator();
|
if (animate && parent != null && mIsFocusAnimationFlagActive) {
|
||||||
|
|
||||||
// When defocusing, the notification needs to shrink. Therefore, we need to free
|
|
||||||
// up the space that is needed for the RemoteInputView. This is done by setting
|
|
||||||
// a negative top margin of the height difference of the RemoteInputView and its
|
|
||||||
// sibling (the actions_container_layout containing the Reply button)
|
|
||||||
if (mDefocusTargetHeight != null && mDefocusTargetHeight < getHeight()
|
|
||||||
&& mDefocusTargetHeight >= 0
|
|
||||||
&& getLayoutParams() instanceof FrameLayout.LayoutParams) {
|
|
||||||
int heightToShrink = getHeight() - mDefocusTargetHeight;
|
|
||||||
FrameLayout.LayoutParams layoutParams =
|
|
||||||
(FrameLayout.LayoutParams) getLayoutParams();
|
|
||||||
layoutParams.topMargin = -heightToShrink;
|
|
||||||
setLayoutParams(layoutParams);
|
|
||||||
((ViewGroup) getParent().getParent()).setClipChildren(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
ViewGroup grandParent = (ViewGroup) parent.getParent();
|
||||||
|
ViewGroupOverlay overlay = parent.getOverlay();
|
||||||
|
|
||||||
|
// After adding this RemoteInputView to the overlay of the parent (and thus removing
|
||||||
|
// it from the parent itself), the parent will shrink in height. This causes the
|
||||||
|
// overlay to be moved. To correct the position of the overlay we need to offset it.
|
||||||
|
int overlayOffsetY = getMaxSiblingHeight() - getHeight();
|
||||||
|
overlay.add(this);
|
||||||
|
if (grandParent != null) grandParent.setClipChildren(false);
|
||||||
|
|
||||||
|
Animator animator = getDefocusAnimator(overlayOffsetY);
|
||||||
|
View self = this;
|
||||||
animator.addListener(new AnimatorListenerAdapter() {
|
animator.addListener(new AnimatorListenerAdapter() {
|
||||||
@Override
|
@Override
|
||||||
public void onAnimationEnd(Animator animation) {
|
public void onAnimationEnd(Animator animation) {
|
||||||
//reset top margin after the animation
|
overlay.remove(self);
|
||||||
if (getLayoutParams() instanceof FrameLayout.LayoutParams) {
|
parent.addView(self);
|
||||||
FrameLayout.LayoutParams layoutParams =
|
if (grandParent != null) grandParent.setClipChildren(true);
|
||||||
(FrameLayout.LayoutParams) getLayoutParams();
|
|
||||||
layoutParams.topMargin = 0;
|
|
||||||
setLayoutParams(layoutParams);
|
|
||||||
((ViewGroup) getParent().getParent()).setClipChildren(true);
|
|
||||||
}
|
|
||||||
setVisibility(GONE);
|
setVisibility(GONE);
|
||||||
if (mWrapper != null) {
|
if (mWrapper != null) {
|
||||||
mWrapper.setRemoteInputVisible(false);
|
mWrapper.setRemoteInputVisible(false);
|
||||||
@@ -609,7 +587,7 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets whether the feature flag for the updated inline reply animation is active or not.
|
* Sets whether the feature flag for the revised inline reply animation is active or not.
|
||||||
* @param active
|
* @param active
|
||||||
*/
|
*/
|
||||||
public void setIsFocusAnimationFlagActive(boolean active) {
|
public void setIsFocusAnimationFlagActive(boolean active) {
|
||||||
@@ -846,6 +824,23 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return max sibling height (0 in case of no siblings)
|
||||||
|
*/
|
||||||
|
public int getMaxSiblingHeight() {
|
||||||
|
ViewGroup parentView = (ViewGroup) getParent();
|
||||||
|
int maxHeight = 0;
|
||||||
|
if (parentView == null) return 0;
|
||||||
|
for (int i = 0; i < parentView.getChildCount(); i++) {
|
||||||
|
View siblingView = parentView.getChildAt(i);
|
||||||
|
if (siblingView != this) maxHeight = Math.max(maxHeight, siblingView.getHeight());
|
||||||
|
}
|
||||||
|
return maxHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an animator for the focus animation.
|
||||||
|
*/
|
||||||
private Animator getFocusAnimator(View crossFadeView) {
|
private Animator getFocusAnimator(View crossFadeView) {
|
||||||
final Animator alphaAnimator = ObjectAnimator.ofFloat(this, View.ALPHA, 0f, 1f);
|
final Animator alphaAnimator = ObjectAnimator.ofFloat(this, View.ALPHA, 0f, 1f);
|
||||||
alphaAnimator.setStartDelay(FOCUS_ANIMATION_FADE_IN_DELAY);
|
alphaAnimator.setStartDelay(FOCUS_ANIMATION_FADE_IN_DELAY);
|
||||||
@@ -854,7 +849,7 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene
|
|||||||
|
|
||||||
ValueAnimator scaleAnimator = ValueAnimator.ofFloat(FOCUS_ANIMATION_MIN_SCALE, 1f);
|
ValueAnimator scaleAnimator = ValueAnimator.ofFloat(FOCUS_ANIMATION_MIN_SCALE, 1f);
|
||||||
scaleAnimator.addUpdateListener(valueAnimator -> {
|
scaleAnimator.addUpdateListener(valueAnimator -> {
|
||||||
setFocusAnimationScaleY((float) scaleAnimator.getAnimatedValue());
|
setFocusAnimationScaleY((float) scaleAnimator.getAnimatedValue(), 0);
|
||||||
});
|
});
|
||||||
scaleAnimator.setDuration(FOCUS_ANIMATION_TOTAL_DURATION);
|
scaleAnimator.setDuration(FOCUS_ANIMATION_TOTAL_DURATION);
|
||||||
scaleAnimator.setInterpolator(InterpolatorsAndroidX.FAST_OUT_SLOW_IN);
|
scaleAnimator.setInterpolator(InterpolatorsAndroidX.FAST_OUT_SLOW_IN);
|
||||||
@@ -875,21 +870,26 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene
|
|||||||
return animatorSet;
|
return animatorSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Animator getDefocusAnimator() {
|
/**
|
||||||
|
* Creates an animator for the defocus animation.
|
||||||
|
*
|
||||||
|
* @param offsetY The RemoteInputView will be offset by offsetY during the animation
|
||||||
|
*/
|
||||||
|
private Animator getDefocusAnimator(int offsetY) {
|
||||||
final Animator alphaAnimator = ObjectAnimator.ofFloat(this, View.ALPHA, 1f, 0f);
|
final Animator alphaAnimator = ObjectAnimator.ofFloat(this, View.ALPHA, 1f, 0f);
|
||||||
alphaAnimator.setDuration(FOCUS_ANIMATION_CROSSFADE_DURATION);
|
alphaAnimator.setDuration(FOCUS_ANIMATION_CROSSFADE_DURATION);
|
||||||
alphaAnimator.setInterpolator(InterpolatorsAndroidX.LINEAR);
|
alphaAnimator.setInterpolator(InterpolatorsAndroidX.LINEAR);
|
||||||
|
|
||||||
ValueAnimator scaleAnimator = ValueAnimator.ofFloat(1f, FOCUS_ANIMATION_MIN_SCALE);
|
ValueAnimator scaleAnimator = ValueAnimator.ofFloat(1f, FOCUS_ANIMATION_MIN_SCALE);
|
||||||
scaleAnimator.addUpdateListener(valueAnimator -> {
|
scaleAnimator.addUpdateListener(valueAnimator -> {
|
||||||
setFocusAnimationScaleY((float) scaleAnimator.getAnimatedValue());
|
setFocusAnimationScaleY((float) scaleAnimator.getAnimatedValue(), offsetY);
|
||||||
});
|
});
|
||||||
scaleAnimator.setDuration(FOCUS_ANIMATION_TOTAL_DURATION);
|
scaleAnimator.setDuration(FOCUS_ANIMATION_TOTAL_DURATION);
|
||||||
scaleAnimator.setInterpolator(InterpolatorsAndroidX.FAST_OUT_SLOW_IN);
|
scaleAnimator.setInterpolator(InterpolatorsAndroidX.FAST_OUT_SLOW_IN);
|
||||||
scaleAnimator.addListener(new AnimatorListenerAdapter() {
|
scaleAnimator.addListener(new AnimatorListenerAdapter() {
|
||||||
@Override
|
@Override
|
||||||
public void onAnimationEnd(Animator animation, boolean isReverse) {
|
public void onAnimationEnd(Animator animation, boolean isReverse) {
|
||||||
setFocusAnimationScaleY(1f);
|
setFocusAnimationScaleY(1f /* scaleY */, 0 /* verticalOffset */);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -901,15 +901,21 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene
|
|||||||
/**
|
/**
|
||||||
* Sets affected view properties for a vertical scale animation
|
* Sets affected view properties for a vertical scale animation
|
||||||
*
|
*
|
||||||
* @param scaleY desired vertical view scale
|
* @param scaleY desired vertical view scale
|
||||||
|
* @param verticalOffset vertical offset to apply to the RemoteInputView during the animation
|
||||||
*/
|
*/
|
||||||
private void setFocusAnimationScaleY(float scaleY) {
|
private void setFocusAnimationScaleY(float scaleY, int verticalOffset) {
|
||||||
int verticalBoundOffset = (int) ((1f - scaleY) * 0.5f * mContentView.getHeight());
|
int verticalBoundOffset = (int) ((1f - scaleY) * 0.5f * mContentView.getHeight());
|
||||||
mContentBackgroundBounds = new Rect(0, verticalBoundOffset, mContentView.getWidth(),
|
Rect contentBackgroundBounds = new Rect(0, verticalBoundOffset, mContentView.getWidth(),
|
||||||
mContentView.getHeight() - verticalBoundOffset);
|
mContentView.getHeight() - verticalBoundOffset);
|
||||||
mContentBackground.setBounds(mContentBackgroundBounds);
|
mContentBackground.setBounds(contentBackgroundBounds);
|
||||||
mContentView.setBackground(mContentBackground);
|
mContentView.setBackground(mContentBackground);
|
||||||
setTranslationY(verticalBoundOffset);
|
if (scaleY == 1f) {
|
||||||
|
mContentBackgroundBounds = null;
|
||||||
|
} else {
|
||||||
|
mContentBackgroundBounds = contentBackgroundBounds;
|
||||||
|
}
|
||||||
|
setTranslationY(verticalBoundOffset + verticalOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Handler for button click on send action in IME. */
|
/** Handler for button click on send action in IME. */
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ import android.view.ViewRootImpl;
|
|||||||
import android.view.inputmethod.EditorInfo;
|
import android.view.inputmethod.EditorInfo;
|
||||||
import android.view.inputmethod.InputConnection;
|
import android.view.inputmethod.InputConnection;
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
|
import android.widget.FrameLayout;
|
||||||
import android.widget.ImageButton;
|
import android.widget.ImageButton;
|
||||||
import android.window.OnBackInvokedCallback;
|
import android.window.OnBackInvokedCallback;
|
||||||
import android.window.OnBackInvokedDispatcher;
|
import android.window.OnBackInvokedDispatcher;
|
||||||
@@ -414,7 +415,9 @@ public class RemoteInputViewTest extends SysuiTestCase {
|
|||||||
mDependency,
|
mDependency,
|
||||||
TestableLooper.get(this));
|
TestableLooper.get(this));
|
||||||
ExpandableNotificationRow row = helper.createRow();
|
ExpandableNotificationRow row = helper.createRow();
|
||||||
|
FrameLayout remoteInputViewParent = new FrameLayout(mContext);
|
||||||
RemoteInputView view = RemoteInputView.inflate(mContext, null, row.getEntry(), mController);
|
RemoteInputView view = RemoteInputView.inflate(mContext, null, row.getEntry(), mController);
|
||||||
|
remoteInputViewParent.addView(view);
|
||||||
bindController(view, row.getEntry());
|
bindController(view, row.getEntry());
|
||||||
|
|
||||||
// Start defocus animation
|
// Start defocus animation
|
||||||
|
|||||||
Reference in New Issue
Block a user