Merge "Fix Notification view transformations in RTL" into sc-dev am: 37781305bd am: 14d716269e

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/14722830

Change-Id: I0b8393fe737d7f0255177c579fa647e92186bad1
This commit is contained in:
Jeff DeCew
2021-05-26 03:03:55 +00:00
committed by Automerger Merge Worker
4 changed files with 62 additions and 27 deletions

View File

@@ -100,6 +100,7 @@
<!-- For notification icons for which targetSdk < L, this caches whether the icon is grayscale --> <!-- For notification icons for which targetSdk < L, this caches whether the icon is grayscale -->
<item type="id" name="icon_is_grayscale" /> <item type="id" name="icon_is_grayscale" />
<item type="id" name="image_icon_tag" /> <item type="id" name="image_icon_tag" />
<item type="id" name="align_transform_end_tag" />
<item type="id" name="contains_transformed_view" /> <item type="id" name="contains_transformed_view" />
<item type="id" name="is_clicked_heads_up_tag" /> <item type="id" name="is_clicked_heads_up_tag" />

View File

@@ -98,20 +98,20 @@ public class TextViewTransformState extends TransformState {
int lineCount = mText.getLineCount(); int lineCount = mText.getLineCount();
return lineCount == 1 && lineCount == otherTvs.mText.getLineCount() return lineCount == 1 && lineCount == otherTvs.mText.getLineCount()
&& getEllipsisCount() == otherTvs.getEllipsisCount() && getEllipsisCount() == otherTvs.getEllipsisCount()
&& getViewHeight() != otherTvs.getViewHeight(); && getContentHeight() != otherTvs.getContentHeight();
} }
@Override @Override
protected int getViewWidth() { protected int getContentWidth() {
Layout l = mText.getLayout(); Layout l = mText.getLayout();
if (l != null) { if (l != null) {
return (int) l.getLineWidth(0); return (int) l.getLineWidth(0);
} }
return super.getViewWidth(); return super.getContentWidth();
} }
@Override @Override
protected int getViewHeight() { protected int getContentHeight() {
return mText.getLineHeight(); return mText.getLineHeight();
} }

View File

@@ -41,6 +41,7 @@ public class TransformState {
public static final int TRANSFORM_X = 0x1; public static final int TRANSFORM_X = 0x1;
public static final int TRANSFORM_Y = 0x10; public static final int TRANSFORM_Y = 0x10;
public static final int TRANSFORM_ALL = TRANSFORM_X | TRANSFORM_Y; public static final int TRANSFORM_ALL = TRANSFORM_X | TRANSFORM_Y;
public static final int ALIGN_END_TAG = R.id.align_transform_end_tag;
private static final float UNDEFINED = -1f; private static final float UNDEFINED = -1f;
private static final int TRANSFORMATION_START_X = R.id.transformation_start_x_tag; private static final int TRANSFORMATION_START_X = R.id.transformation_start_x_tag;
@@ -78,11 +79,13 @@ public class TransformState {
private boolean mSameAsAny; private boolean mSameAsAny;
private float mTransformationEndY = UNDEFINED; private float mTransformationEndY = UNDEFINED;
private float mTransformationEndX = UNDEFINED; private float mTransformationEndX = UNDEFINED;
private boolean mAlignEnd;
protected Interpolator mDefaultInterpolator = Interpolators.FAST_OUT_SLOW_IN; protected Interpolator mDefaultInterpolator = Interpolators.FAST_OUT_SLOW_IN;
public void initFrom(View view, TransformInfo transformInfo) { public void initFrom(View view, TransformInfo transformInfo) {
mTransformedView = view; mTransformedView = view;
mTransformInfo = transformInfo; mTransformInfo = transformInfo;
mAlignEnd = Boolean.TRUE.equals(view.getTag(ALIGN_END_TAG));
} }
/** /**
@@ -135,13 +138,16 @@ public class TransformState {
final View transformedView = mTransformedView; final View transformedView = mTransformedView;
boolean transformX = (transformationFlags & TRANSFORM_X) != 0; boolean transformX = (transformationFlags & TRANSFORM_X) != 0;
boolean transformY = (transformationFlags & TRANSFORM_Y) != 0; boolean transformY = (transformationFlags & TRANSFORM_Y) != 0;
int viewHeight = getViewHeight(); int ownContentHeight = getContentHeight();
int otherHeight = otherState.getViewHeight(); int otherContentHeight = otherState.getContentHeight();
boolean differentHeight = otherHeight != viewHeight && otherHeight != 0 && viewHeight != 0; boolean differentHeight = otherContentHeight != ownContentHeight
int viewWidth = getViewWidth(); && otherContentHeight != 0 && ownContentHeight != 0;
int otherWidth = otherState.getViewWidth(); int ownContentWidth = getContentWidth();
boolean differentWidth = otherWidth != viewWidth && otherWidth != 0 && viewWidth != 0; int otherContentWidth = otherState.getContentWidth();
boolean transformScale = transformScale(otherState) && (differentHeight || differentWidth); boolean differentWidth = otherContentWidth != ownContentWidth
&& otherContentWidth != 0 && ownContentWidth != 0;
boolean transformScale = (differentHeight || differentWidth) && transformScale(otherState);
boolean transformRightEdge = transformRightEdge(otherState);
// lets animate the positions correctly // lets animate the positions correctly
if (transformationAmount == 0.0f if (transformationAmount == 0.0f
|| transformX && getTransformationStartX() == UNDEFINED || transformX && getTransformationStartX() == UNDEFINED
@@ -159,7 +165,14 @@ public class TransformState {
if (customTransformation == null if (customTransformation == null
|| !customTransformation.initTransformation(this, otherState)) { || !customTransformation.initTransformation(this, otherState)) {
if (transformX) { if (transformX) {
setTransformationStartX(otherPosition[0] - ownStablePosition[0]); if (transformRightEdge) {
int otherViewWidth = otherState.getTransformedView().getWidth();
int ownViewWidth = transformedView.getWidth();
setTransformationStartX((otherPosition[0] + otherViewWidth)
- (ownStablePosition[0] + ownViewWidth));
} else {
setTransformationStartX(otherPosition[0] - ownStablePosition[0]);
}
} }
if (transformY) { if (transformY) {
setTransformationStartY(otherPosition[1] - ownStablePosition[1]); setTransformationStartY(otherPosition[1] - ownStablePosition[1]);
@@ -167,15 +180,15 @@ public class TransformState {
// we also want to animate the scale if we're the same // we also want to animate the scale if we're the same
View otherView = otherState.getTransformedView(); View otherView = otherState.getTransformedView();
if (transformScale && differentWidth) { if (transformScale && differentWidth) {
setTransformationStartScaleX(otherWidth * otherView.getScaleX() setTransformationStartScaleX(otherContentWidth * otherView.getScaleX()
/ (float) viewWidth); / (float) ownContentWidth);
transformedView.setPivotX(0); transformedView.setPivotX(transformRightEdge ? transformedView.getWidth() : 0);
} else { } else {
setTransformationStartScaleX(UNDEFINED); setTransformationStartScaleX(UNDEFINED);
} }
if (transformScale && differentHeight) { if (transformScale && differentHeight) {
setTransformationStartScaleY(otherHeight * otherView.getScaleY() setTransformationStartScaleY(otherContentHeight * otherView.getScaleY()
/ (float) viewHeight); / (float) ownContentHeight);
transformedView.setPivotY(0); transformedView.setPivotY(0);
} else { } else {
setTransformationStartScaleY(UNDEFINED); setTransformationStartScaleY(UNDEFINED);
@@ -239,11 +252,19 @@ public class TransformState {
} }
} }
protected int getViewWidth() { /**
* The width of the content of this view. For some views, like TextViews, this will be the
* width of content inside the view which is transforming, rather than the view's full width.
*/
protected int getContentWidth() {
return mTransformedView.getWidth(); return mTransformedView.getWidth();
} }
protected int getViewHeight() { /**
* The height of the content of this view. For some views, like TextViews, this will be the
* height of content inside the view which is transforming, rather than the view's full height.
*/
protected int getContentHeight() {
return mTransformedView.getHeight(); return mTransformedView.getHeight();
} }
@@ -251,6 +272,12 @@ public class TransformState {
return sameAs(otherState); return sameAs(otherState);
} }
protected boolean transformRightEdge(TransformState otherState) {
boolean alignEnd = mAlignEnd && otherState.mAlignEnd;
boolean isRtl = mTransformedView.isLayoutRtl() && otherState.mTransformedView.isLayoutRtl();
return alignEnd ^ isRtl;
}
/** /**
* Transforms the {@link #mTransformedView} to the given transformviewstate * Transforms the {@link #mTransformedView} to the given transformviewstate
* @param otherState the state to transform from * @param otherState the state to transform from
@@ -302,6 +329,9 @@ public class TransformState {
boolean transformX = (transformationFlags & TRANSFORM_X) != 0; boolean transformX = (transformationFlags & TRANSFORM_X) != 0;
boolean transformY = (transformationFlags & TRANSFORM_Y) != 0; boolean transformY = (transformationFlags & TRANSFORM_Y) != 0;
boolean transformScale = transformScale(otherState); boolean transformScale = transformScale(otherState);
boolean transformRightEdge = transformRightEdge(otherState);
int ownContentWidth = getContentWidth();
int otherContentWidth = otherState.getContentWidth();
// lets animate the positions correctly // lets animate the positions correctly
if (transformationAmount == 0.0f) { if (transformationAmount == 0.0f) {
if (transformX) { if (transformX) {
@@ -316,14 +346,13 @@ public class TransformState {
: transformedView.getTranslationY(); : transformedView.getTranslationY();
setTransformationStartY(start); setTransformationStartY(start);
} }
View otherView = otherState.getTransformedView(); if (transformScale && otherContentWidth != ownContentWidth) {
if (transformScale && otherState.getViewWidth() != getViewWidth()) {
setTransformationStartScaleX(transformedView.getScaleX()); setTransformationStartScaleX(transformedView.getScaleX());
transformedView.setPivotX(0); transformedView.setPivotX(transformRightEdge ? transformedView.getWidth() : 0);
} else { } else {
setTransformationStartScaleX(UNDEFINED); setTransformationStartScaleX(UNDEFINED);
} }
if (transformScale && otherState.getViewHeight() != getViewHeight()) { if (transformScale && otherState.getContentHeight() != getContentHeight()) {
setTransformationStartScaleY(transformedView.getScaleY()); setTransformationStartScaleY(transformedView.getScaleY());
transformedView.setPivotY(0); transformedView.setPivotY(0);
} else { } else {
@@ -336,7 +365,11 @@ public class TransformState {
int[] otherStablePosition = otherState.getLaidOutLocationOnScreen(); int[] otherStablePosition = otherState.getLaidOutLocationOnScreen();
int[] ownPosition = getLaidOutLocationOnScreen(); int[] ownPosition = getLaidOutLocationOnScreen();
if (transformX) { if (transformX) {
float endX = otherStablePosition[0] - ownPosition[0]; int ownViewWidth = transformedView.getWidth();
int otherViewWidth = otherState.getTransformedView().getWidth();
float endX = transformRightEdge
? (otherStablePosition[0] + otherViewWidth) - (ownPosition[0] + ownViewWidth)
: otherStablePosition[0] - ownPosition[0];
float interpolation = interpolatedValue; float interpolation = interpolatedValue;
if (customTransformation != null) { if (customTransformation != null) {
if (customTransformation.customTransformTarget(this, otherState)) { if (customTransformation.customTransformTarget(this, otherState)) {
@@ -370,19 +403,18 @@ public class TransformState {
interpolation)); interpolation));
} }
if (transformScale) { if (transformScale) {
View otherView = otherState.getTransformedView();
float transformationStartScaleX = getTransformationStartScaleX(); float transformationStartScaleX = getTransformationStartScaleX();
if (transformationStartScaleX != UNDEFINED) { if (transformationStartScaleX != UNDEFINED) {
transformedView.setScaleX( transformedView.setScaleX(
NotificationUtils.interpolate(transformationStartScaleX, NotificationUtils.interpolate(transformationStartScaleX,
(otherState.getViewWidth() / (float) getViewWidth()), (otherContentWidth / (float) ownContentWidth),
interpolatedValue)); interpolatedValue));
} }
float transformationStartScaleY = getTransformationStartScaleY(); float transformationStartScaleY = getTransformationStartScaleY();
if (transformationStartScaleY != UNDEFINED) { if (transformationStartScaleY != UNDEFINED) {
transformedView.setScaleY( transformedView.setScaleY(
NotificationUtils.interpolate(transformationStartScaleY, NotificationUtils.interpolate(transformationStartScaleY,
(otherState.getViewHeight() / (float) getViewHeight()), (otherState.getContentHeight() / (float) getContentHeight()),
interpolatedValue)); interpolatedValue));
} }
} }
@@ -529,6 +561,7 @@ public class TransformState {
mSameAsAny = false; mSameAsAny = false;
mTransformationEndX = UNDEFINED; mTransformationEndX = UNDEFINED;
mTransformationEndY = UNDEFINED; mTransformationEndY = UNDEFINED;
mAlignEnd = false;
mDefaultInterpolator = Interpolators.FAST_OUT_SLOW_IN; mDefaultInterpolator = Interpolators.FAST_OUT_SLOW_IN;
} }

View File

@@ -151,6 +151,7 @@ public class NotificationTemplateViewWrapper extends NotificationHeaderViewWrapp
mRightIcon = mView.findViewById(com.android.internal.R.id.right_icon); mRightIcon = mView.findViewById(com.android.internal.R.id.right_icon);
if (mRightIcon != null) { if (mRightIcon != null) {
mRightIcon.setTag(ImageTransformState.ICON_TAG, getRightIcon(sbn.getNotification())); mRightIcon.setTag(ImageTransformState.ICON_TAG, getRightIcon(sbn.getNotification()));
mRightIcon.setTag(TransformState.ALIGN_END_TAG, true);
} }
mLeftIcon = mView.findViewById(com.android.internal.R.id.left_icon); mLeftIcon = mView.findViewById(com.android.internal.R.id.left_icon);
if (mLeftIcon != null) { if (mLeftIcon != null) {