Fixed alignItems: baseline for <Text> elements on Android (#31575)

Summary:
This fixes https://github.com/facebook/react-native/issues/20666 and https://github.com/facebook/react-native/issues/21918.

This is pretty much the same as 51b3529f6c but implemented for Android.
Now <Text> exposes the actual base-line offset value that allows Yoga to position it properly when `alignItems: baseline` is requested.

## Changelog
[Android][Fixed] - Fixed `alignItems: baseline` for <Text> elements on Android

Pull Request resolved: https://github.com/facebook/react-native/pull/31575

Test Plan:
The same test case that we have for iOS.
Before:
<img width="487" alt="Screen Shot 2021-05-22 at 7 03 18 PM" src="https://user-images.githubusercontent.com/22032/119277516-d62b5100-bbe5-11eb-9141-3abe56e1a476.png">

After:
<img width="487" alt="Screen Shot 2021-05-22 at 7 01 51 PM" src="https://user-images.githubusercontent.com/22032/119277518-d75c7e00-bbe5-11eb-9139-4c6b5fcd9157.png">

Reviewed By: JoshuaGross

Differential Revision: D28631468

Pulled By: yungsters

fbshipit-source-id: 7c259e469d19d8344298319f066b8437dfdedad0
This commit is contained in:
Valentin Shergin
2021-08-26 21:46:37 -07:00
committed by Facebook GitHub Bot
parent 5d6484e0a8
commit 1acf334614
2 changed files with 78 additions and 0 deletions
@@ -32,6 +32,7 @@ import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.uimanager.UIViewOperationQueue;
import com.facebook.react.uimanager.annotations.ReactProp;
import com.facebook.react.uimanager.events.RCTEventEmitter;
import com.facebook.yoga.YogaBaselineFunction;
import com.facebook.yoga.YogaConstants;
import com.facebook.yoga.YogaDirection;
import com.facebook.yoga.YogaMeasureFunction;
@@ -159,6 +160,20 @@ public class ReactTextShadowNode extends ReactBaseTextShadowNode {
}
};
private final YogaBaselineFunction mTextBaselineFunction =
new YogaBaselineFunction() {
@Override
public float baseline(YogaNode node, float width, float height) {
Spannable text =
Assertions.assertNotNull(
mPreparedSpannableText,
"Spannable element has not been prepared in onBeforeLayout");
Layout layout = measureSpannedText(text, width, YogaMeasureMode.EXACTLY);
return layout.getLineBaseline(layout.getLineCount() - 1);
}
};
public ReactTextShadowNode() {
this(null);
}
@@ -171,6 +186,7 @@ public class ReactTextShadowNode extends ReactBaseTextShadowNode {
private void initMeasureFunction() {
if (!isVirtual()) {
setMeasureFunction(mTextMeasureFunction);
setBaselineFunction(mTextBaselineFunction);
}
}