Skip to content

Commit 1acf334

Browse files
shergin-cbfacebook-github-bot
authored andcommitted
Fixed alignItems: baseline for <Text> elements on Android (#31575)
Summary: This fixes #20666 and #21918. This is pretty much the same as 51b3529 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: #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
1 parent 5d6484e commit 1acf334

File tree

2 files changed

+78
-0
lines changed

2 files changed

+78
-0
lines changed

ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextShadowNode.java

+16
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import com.facebook.react.uimanager.UIViewOperationQueue;
3333
import com.facebook.react.uimanager.annotations.ReactProp;
3434
import com.facebook.react.uimanager.events.RCTEventEmitter;
35+
import com.facebook.yoga.YogaBaselineFunction;
3536
import com.facebook.yoga.YogaConstants;
3637
import com.facebook.yoga.YogaDirection;
3738
import com.facebook.yoga.YogaMeasureFunction;
@@ -159,6 +160,20 @@ public long measure(
159160
}
160161
};
161162

163+
private final YogaBaselineFunction mTextBaselineFunction =
164+
new YogaBaselineFunction() {
165+
@Override
166+
public float baseline(YogaNode node, float width, float height) {
167+
Spannable text =
168+
Assertions.assertNotNull(
169+
mPreparedSpannableText,
170+
"Spannable element has not been prepared in onBeforeLayout");
171+
172+
Layout layout = measureSpannedText(text, width, YogaMeasureMode.EXACTLY);
173+
return layout.getLineBaseline(layout.getLineCount() - 1);
174+
}
175+
};
176+
162177
public ReactTextShadowNode() {
163178
this(null);
164179
}
@@ -171,6 +186,7 @@ public ReactTextShadowNode(@Nullable ReactTextViewManagerCallback reactTextViewM
171186
private void initMeasureFunction() {
172187
if (!isVirtual()) {
173188
setMeasureFunction(mTextMeasureFunction);
189+
setBaselineFunction(mTextBaselineFunction);
174190
}
175191
}
176192

packages/rn-tester/js/examples/Text/TextExample.android.js

+62
Original file line numberDiff line numberDiff line change
@@ -884,6 +884,62 @@ const styles = StyleSheet.create({
884884
alignSelf: 'center',
885885
},
886886
});
887+
888+
function TextBaseLineLayoutExample(props: {}): React.Node {
889+
const texts = [];
890+
for (let i = 9; i >= 0; i--) {
891+
texts.push(
892+
<Text
893+
key={i}
894+
style={{fontSize: 8 + i * 5, maxWidth: 20, backgroundColor: '#eee'}}>
895+
{i}
896+
</Text>,
897+
);
898+
}
899+
900+
const marker = (
901+
<View style={{width: 20, height: 20, backgroundColor: 'gray'}} />
902+
);
903+
const subtitleStyle = {fontSize: 16, marginTop: 8, fontWeight: 'bold'};
904+
905+
return (
906+
<View>
907+
<Text style={subtitleStyle}>{'Nested <Text/>s:'}</Text>
908+
<View style={{flexDirection: 'row', alignItems: 'baseline'}}>
909+
{marker}
910+
<Text>{texts}</Text>
911+
{marker}
912+
</View>
913+
914+
<Text style={subtitleStyle}>{'Array of <Text/>s in <View>:'}</Text>
915+
<View style={{flexDirection: 'row', alignItems: 'baseline'}}>
916+
{marker}
917+
{texts}
918+
{marker}
919+
</View>
920+
921+
<Text style={subtitleStyle}>{'Interleaving <View> and <Text>:'}</Text>
922+
<View style={{flexDirection: 'row', alignItems: 'baseline'}}>
923+
{marker}
924+
<Text selectable={true}>
925+
Some text.
926+
<View
927+
style={{
928+
flexDirection: 'row',
929+
alignItems: 'baseline',
930+
backgroundColor: '#eee',
931+
}}>
932+
{marker}
933+
<Text>Text inside View.</Text>
934+
{marker}
935+
</View>
936+
</Text>
937+
{marker}
938+
</View>
939+
</View>
940+
);
941+
}
942+
887943
exports.title = 'Text';
888944
exports.documentationURL = 'https://reactnative.dev/docs/text';
889945
exports.category = 'Basic';
@@ -895,4 +951,10 @@ exports.examples = [
895951
return <TextExample />;
896952
},
897953
},
954+
{
955+
title: "Text `alignItems: 'baseline'` style",
956+
render: function(): React.Node {
957+
return <TextBaseLineLayoutExample />;
958+
},
959+
},
898960
];

0 commit comments

Comments
 (0)