From 843d57ecc15632e2a6452d58d8ba032e1306105e Mon Sep 17 00:00:00 2001 From: Pieter De Baets Date: Wed, 22 Feb 2023 03:17:24 -0800 Subject: [PATCH] Fix TextView alignment being reset on state updates Summary: Changelog: [Android][Fixed] Resolved bug with Text components in new arch losing text alignment state. Reviewed By: mdvacca Differential Revision: D34108943 fbshipit-source-id: 3992e9406345be919b5e3595fc1f9e61cf67a699 # Conflicts: # ReactAndroid/src/main/java/com/facebook/react/views/text/TextAttributeProps.java # ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java --- .../react/views/text/ReactTextView.java | 16 +++++----- .../views/text/ReactTextViewManager.java | 18 +++++++---- .../react/views/text/TextAttributeProps.java | 30 +++++++++---------- .../react/views/textinput/ReactEditText.java | 5 ++++ .../textinput/ReactTextInputManager.java | 17 ++++++----- 5 files changed, 52 insertions(+), 34 deletions(-) diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextView.java b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextView.java index e5e405682f0..6e742793eaf 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextView.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextView.java @@ -54,7 +54,6 @@ public class ReactTextView extends AppCompatTextView implements ReactCompoundVie private boolean mContainsImages; private final int mDefaultGravityHorizontal; private final int mDefaultGravityVertical; - private int mTextAlign; private int mNumberOfLines; private TextUtils.TruncateAt mEllipsizeLocation; private boolean mAdjustsFontSizeToFit; @@ -69,8 +68,7 @@ public class ReactTextView extends AppCompatTextView implements ReactCompoundVie super(context); // Get these defaults only during the constructor - these should never be set otherwise - mDefaultGravityHorizontal = - getGravity() & (Gravity.HORIZONTAL_GRAVITY_MASK | Gravity.RELATIVE_HORIZONTAL_GRAVITY_MASK); + mDefaultGravityHorizontal = getGravityHorizontal(); mDefaultGravityVertical = getGravity() & Gravity.VERTICAL_GRAVITY_MASK; initView(); @@ -89,10 +87,10 @@ public class ReactTextView extends AppCompatTextView implements ReactCompoundVie mReactBackgroundManager = new ReactViewBackgroundManager(this); - mTextAlign = Gravity.NO_GRAVITY; mNumberOfLines = ViewDefaults.NUMBER_OF_LINES; mAdjustsFontSizeToFit = false; mLinkifyMaskType = 0; + mNotifyOnInlineViewLayout = false; mTextIsSelectable = false; mEllipsizeLocation = TextUtils.TruncateAt.END; @@ -392,10 +390,9 @@ public class ReactTextView extends AppCompatTextView implements ReactCompoundVie } int nextTextAlign = update.getTextAlign(); - if (mTextAlign != nextTextAlign) { - mTextAlign = nextTextAlign; + if (nextTextAlign != getGravityHorizontal()) { + setGravityHorizontal(nextTextAlign); } - setGravityHorizontal(mTextAlign); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (getBreakStrategy() != update.getTextBreakStrategy()) { setBreakStrategy(update.getTextBreakStrategy()); @@ -552,6 +549,11 @@ public class ReactTextView extends AppCompatTextView implements ReactCompoundVie return false; } + /* package */ int getGravityHorizontal() { + return getGravity() + & (Gravity.HORIZONTAL_GRAVITY_MASK | Gravity.RELATIVE_HORIZONTAL_GRAVITY_MASK); + } + /* package */ void setGravityHorizontal(int gravityHorizontal) { if (gravityHorizontal == 0) { gravityHorizontal = mDefaultGravityHorizontal; diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextViewManager.java b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextViewManager.java index 0c8a7f0621b..705223f832d 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextViewManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextViewManager.java @@ -8,6 +8,7 @@ package com.facebook.react.views.text; import android.content.Context; +import android.os.Build; import android.text.Spannable; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -23,6 +24,7 @@ import com.facebook.react.uimanager.ReactAccessibilityDelegate; import com.facebook.react.uimanager.ReactStylesDiffMap; import com.facebook.react.uimanager.StateWrapper; import com.facebook.react.uimanager.ThemedReactContext; +import com.facebook.react.uimanager.ViewProps; import com.facebook.yoga.YogaMeasureMode; import java.util.HashMap; import java.util.Map; @@ -148,15 +150,19 @@ public class ReactTextViewManager view.setSpanned(spanned); int textBreakStrategy = - TextAttributeProps.getTextBreakStrategy(paragraphAttributes.getString("textBreakStrategy")); + TextAttributeProps.getTextBreakStrategy( + paragraphAttributes.getString(ViewProps.TEXT_BREAK_STRATEGY)); + int currentJustificationMode = + Build.VERSION.SDK_INT < Build.VERSION_CODES.O ? 0 : view.getJustificationMode(); return new ReactTextUpdate( spanned, state.hasKey("mostRecentEventCount") ? state.getInt("mostRecentEventCount") : -1, false, // TODO add this into local Data - TextAttributeProps.getTextAlignment(props, TextLayoutManager.isRTL(attributedString)), + TextAttributeProps.getTextAlignment( + props, TextLayoutManager.isRTL(attributedString), view.getGravityHorizontal()), textBreakStrategy, - TextAttributeProps.getJustificationMode(props)); + TextAttributeProps.getJustificationMode(props, currentJustificationMode)); } private Object getReactTextUpdate(ReactTextView view, ReactStylesDiffMap props, MapBuffer state) { @@ -171,15 +177,17 @@ public class ReactTextViewManager int textBreakStrategy = TextAttributeProps.getTextBreakStrategy( paragraphAttributes.getString(TextLayoutManagerMapBuffer.PA_KEY_TEXT_BREAK_STRATEGY)); + int currentJustificationMode = + Build.VERSION.SDK_INT < Build.VERSION_CODES.O ? 0 : view.getJustificationMode(); return new ReactTextUpdate( spanned, -1, // UNUSED FOR TEXT false, // TODO add this into local Data TextAttributeProps.getTextAlignment( - props, TextLayoutManagerMapBuffer.isRTL(attributedString)), + props, TextLayoutManagerMapBuffer.isRTL(attributedString), view.getGravityHorizontal()), textBreakStrategy, - TextAttributeProps.getJustificationMode(props)); + TextAttributeProps.getJustificationMode(props, currentJustificationMode)); } @Override diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/text/TextAttributeProps.java b/ReactAndroid/src/main/java/com/facebook/react/views/text/TextAttributeProps.java index 787ab9bb14d..0a14e28af3e 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/text/TextAttributeProps.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/text/TextAttributeProps.java @@ -249,35 +249,35 @@ public class TextAttributeProps { return result; } - public static int getTextAlignment(ReactStylesDiffMap props, boolean isRTL) { - @Nullable - String textAlignPropValue = - props.hasKey(ViewProps.TEXT_ALIGN) ? props.getString(ViewProps.TEXT_ALIGN) : null; - int textAlignment; + public static int getTextAlignment(ReactStylesDiffMap props, boolean isRTL, int defaultValue) { + if (!props.hasKey(ViewProps.TEXT_ALIGN)) { + return defaultValue; + } + String textAlignPropValue = props.getString(ViewProps.TEXT_ALIGN); if ("justify".equals(textAlignPropValue)) { - textAlignment = Gravity.LEFT; + return Gravity.LEFT; } else { if (textAlignPropValue == null || "auto".equals(textAlignPropValue)) { - textAlignment = Gravity.NO_GRAVITY; + return Gravity.NO_GRAVITY; } else if ("left".equals(textAlignPropValue)) { - textAlignment = isRTL ? Gravity.RIGHT : Gravity.LEFT; + return isRTL ? Gravity.RIGHT : Gravity.LEFT; } else if ("right".equals(textAlignPropValue)) { - textAlignment = isRTL ? Gravity.LEFT : Gravity.RIGHT; + return isRTL ? Gravity.LEFT : Gravity.RIGHT; } else if ("center".equals(textAlignPropValue)) { - textAlignment = Gravity.CENTER_HORIZONTAL; + return Gravity.CENTER_HORIZONTAL; } else { throw new JSApplicationIllegalArgumentException("Invalid textAlign: " + textAlignPropValue); } } - return textAlignment; } - public static int getJustificationMode(ReactStylesDiffMap props) { - @Nullable - String textAlignPropValue = - props.hasKey(ViewProps.TEXT_ALIGN) ? props.getString(ViewProps.TEXT_ALIGN) : null; + public static int getJustificationMode(ReactStylesDiffMap props, int defaultValue) { + if (!props.hasKey(ViewProps.TEXT_ALIGN)) { + return defaultValue; + } + String textAlignPropValue = props.getString(ViewProps.TEXT_ALIGN); if ("justify".equals(textAlignPropValue) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { return Layout.JUSTIFICATION_MODE_INTER_WORD; } diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditText.java b/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditText.java index b93aa8eca7d..290bd23f2e0 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditText.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditText.java @@ -911,6 +911,11 @@ public class ReactEditText extends AppCompatEditText } } + /* package */ int getGravityHorizontal() { + return getGravity() + & (Gravity.HORIZONTAL_GRAVITY_MASK | Gravity.RELATIVE_HORIZONTAL_GRAVITY_MASK); + } + /* package */ void setGravityHorizontal(int gravityHorizontal) { if (gravityHorizontal == 0) { gravityHorizontal = mDefaultGravityHorizontal; diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java b/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java index f4451acede3..5fda12a3f7f 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java @@ -1326,10 +1326,7 @@ public class ReactTextInputManager extends BaseViewManager