Skip to content

Commit

Permalink
Fix TextView alignment being reset on state updates
Browse files Browse the repository at this point in the history
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
  • Loading branch information
javache authored and facebook-github-bot committed Feb 22, 2023
1 parent bc749a1 commit 31a8e92
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 37 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -69,8 +68,7 @@ public ReactTextView(Context context) {
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();
Expand All @@ -89,10 +87,10 @@ private void initView() {

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;

Expand Down Expand Up @@ -392,10 +390,9 @@ public void setText(ReactTextUpdate update) {
}

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());
Expand Down Expand Up @@ -552,6 +549,11 @@ public boolean hasOverlappingRendering() {
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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -23,6 +24,7 @@
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;
Expand Down Expand Up @@ -148,15 +150,19 @@ public Object updateState(
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) {
Expand All @@ -171,15 +177,17 @@ private Object getReactTextUpdate(ReactTextView view, ReactStylesDiffMap props,
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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -250,36 +250,36 @@ public static TextAttributeProps fromReadableMap(ReactStylesDiffMap props) {
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 {
FLog.w(ReactConstants.TAG, "Invalid textAlign: " + textAlignPropValue);
textAlignment = Gravity.NO_GRAVITY;
return Gravity.NO_GRAVITY;
}
}
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;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -845,6 +845,11 @@ private void setIntrinsicContentSize() {
}
}

/* package */ int getGravityHorizontal() {
return getGravity()
& (Gravity.HORIZONTAL_GRAVITY_MASK | Gravity.RELATIVE_HORIZONTAL_GRAVITY_MASK);
}

/* package */ void setGravityHorizontal(int gravityHorizontal) {
if (gravityHorizontal == 0) {
gravityHorizontal = mDefaultGravityHorizontal;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1315,10 +1315,7 @@ public Object updateState(
}

ReadableNativeMap state = stateWrapper.getStateData();
if (state == null) {
return null;
}
if (!state.hasKey("attributedString")) {
if (state == null || !state.hasKey("attributedString")) {
return null;
}

Expand All @@ -1336,14 +1333,18 @@ public Object updateState(
attributedString.getArray("fragments").toArrayList().size() > 1;

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 ReactTextUpdate.buildReactTextUpdateFromState(
spanned,
state.getInt("mostRecentEventCount"),
TextAttributeProps.getTextAlignment(props, TextLayoutManager.isRTL(attributedString)),
TextAttributeProps.getTextAlignment(
props, TextLayoutManager.isRTL(attributedString), view.getGravityHorizontal()),
textBreakStrategy,
TextAttributeProps.getJustificationMode(props),
TextAttributeProps.getJustificationMode(props, currentJustificationMode),
containsMultipleFragments);
}

Expand Down Expand Up @@ -1371,14 +1372,16 @@ public Object getReactTextUpdate(ReactEditText view, ReactStylesDiffMap props, M
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 ReactTextUpdate.buildReactTextUpdateFromState(
spanned,
state.getInt(TX_STATE_KEY_MOST_RECENT_EVENT_COUNT),
TextAttributeProps.getTextAlignment(
props, TextLayoutManagerMapBuffer.isRTL(attributedString)),
props, TextLayoutManagerMapBuffer.isRTL(attributedString), view.getGravityHorizontal()),
textBreakStrategy,
TextAttributeProps.getJustificationMode(props),
TextAttributeProps.getJustificationMode(props, currentJustificationMode),
containsMultipleFragments);
}
}

0 comments on commit 31a8e92

Please sign in to comment.