diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextShadowNode.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextShadowNode.java index a66950c7966af6..d53f18a5aa3289 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextShadowNode.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextShadowNode.java @@ -7,7 +7,6 @@ package com.facebook.react.views.text; -import android.annotation.TargetApi; import android.os.Build; import android.text.BoringLayout; import android.text.Layout; @@ -47,7 +46,6 @@ *

The class measures text in {@code } view and feeds native {@link TextView} using {@code * Spannable} object constructed in superclass. */ -@TargetApi(Build.VERSION_CODES.M) public class ReactTextShadowNode extends ReactBaseTextShadowNode { // It's important to pass the ANTI_ALIAS_FLAG flag to the constructor rather than setting it @@ -148,7 +146,7 @@ public long measure( } } - if (android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.Q) { + if (Build.VERSION.SDK_INT > Build.VERSION_CODES.Q) { layoutWidth = (float) Math.ceil(layoutWidth); } float layoutHeight = height; @@ -222,28 +220,22 @@ private Layout measureSpannedText(Spannable text, float width, YogaMeasureMode w || (!YogaConstants.isUndefined(desiredWidth) && desiredWidth <= width))) { // Is used when the width is not known and the text is not boring, ie. if it contains // unicode characters. - int hintWidth = (int) Math.ceil(desiredWidth); - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { - layout = - new StaticLayout(text, textPaint, hintWidth, alignment, 1.f, 0.f, mIncludeFontPadding); - } else { - StaticLayout.Builder builder = - StaticLayout.Builder.obtain(text, 0, text.length(), textPaint, hintWidth) - .setAlignment(alignment) - .setLineSpacing(0.f, 1.f) - .setIncludePad(mIncludeFontPadding) - .setBreakStrategy(mTextBreakStrategy) - .setHyphenationFrequency(mHyphenationFrequency); - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - builder.setJustificationMode(mJustificationMode); - } - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { - builder.setUseLineSpacingFromFallbacks(true); - } - layout = builder.build(); + StaticLayout.Builder builder = + StaticLayout.Builder.obtain(text, 0, text.length(), textPaint, hintWidth) + .setAlignment(alignment) + .setLineSpacing(0.f, 1.f) + .setIncludePad(mIncludeFontPadding) + .setBreakStrategy(mTextBreakStrategy) + .setHyphenationFrequency(mHyphenationFrequency); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + builder.setJustificationMode(mJustificationMode); + } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { + builder.setUseLineSpacingFromFallbacks(true); } + layout = builder.build(); } else if (boring != null && (unconstrainedWidth || boring.width <= width)) { // Is used for single-line, boring text when the width is either unknown or bigger @@ -260,32 +252,25 @@ private Layout measureSpannedText(Spannable text, float width, YogaMeasureMode w mIncludeFontPadding); } else { // Is used for multiline, boring text and the width is known. + // Android 11+ introduces changes in text width calculation which leads to cases + // where the container is measured smaller than text. Math.ceil prevents it + // See T136756103 for investigation + if (Build.VERSION.SDK_INT > Build.VERSION_CODES.Q) { + width = (float) Math.ceil(width); + } - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { - layout = - new StaticLayout( - text, textPaint, (int) width, alignment, 1.f, 0.f, mIncludeFontPadding); - } else { - // Android 11+ introduces changes in text width calculation which leads to cases - // where the container is measured smaller than text. Math.ceil prevents it - // See T136756103 for investigation - if (android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.Q) { - width = (float) Math.ceil(width); - } - - StaticLayout.Builder builder = - StaticLayout.Builder.obtain(text, 0, text.length(), textPaint, (int) width) - .setAlignment(alignment) - .setLineSpacing(0.f, 1.f) - .setIncludePad(mIncludeFontPadding) - .setBreakStrategy(mTextBreakStrategy) - .setHyphenationFrequency(mHyphenationFrequency); + StaticLayout.Builder builder = + StaticLayout.Builder.obtain(text, 0, text.length(), textPaint, (int) width) + .setAlignment(alignment) + .setLineSpacing(0.f, 1.f) + .setIncludePad(mIncludeFontPadding) + .setBreakStrategy(mTextBreakStrategy) + .setHyphenationFrequency(mHyphenationFrequency); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { - builder.setUseLineSpacingFromFallbacks(true); - } - layout = builder.build(); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { + builder.setUseLineSpacingFromFallbacks(true); } + layout = builder.build(); } return layout; } @@ -361,6 +346,7 @@ public void setShouldNotifyOnTextLayout(boolean shouldNotifyOnTextLayout) { } @Override + @Nullable public Iterable calculateLayoutOnChildren() { // Run flexbox on and return the descendants which are inline views. @@ -374,7 +360,7 @@ public Iterable calculateLayoutOnChildren() { "Spannable element has not been prepared in onBeforeLayout"); TextInlineViewPlaceholderSpan[] placeholders = text.getSpans(0, text.length(), TextInlineViewPlaceholderSpan.class); - ArrayList shadowNodes = new ArrayList(placeholders.length); + ArrayList shadowNodes = new ArrayList<>(placeholders.length); for (TextInlineViewPlaceholderSpan placeholder : placeholders) { ReactShadowNode child = mInlineViews.get(placeholder.getReactTag());