Skip to content

Commit

Permalink
Fixed alignItems: baseline for <Text> elements on Android (#31575)
Browse files Browse the repository at this point in the history
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
  • Loading branch information
shergin-cb authored and facebook-github-bot committed Aug 27, 2021
1 parent 5d6484e commit 1acf334
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
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;
Expand Down Expand Up @@ -159,6 +160,20 @@ public long measure(
}
};

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);
}
Expand All @@ -171,6 +186,7 @@ public ReactTextShadowNode(@Nullable ReactTextViewManagerCallback reactTextViewM
private void initMeasureFunction() {
if (!isVirtual()) {
setMeasureFunction(mTextMeasureFunction);
setBaselineFunction(mTextBaselineFunction);
}
}

Expand Down
62 changes: 62 additions & 0 deletions packages/rn-tester/js/examples/Text/TextExample.android.js
Original file line number Diff line number Diff line change
Expand Up @@ -884,6 +884,62 @@ const styles = StyleSheet.create({
alignSelf: 'center',
},
});

function TextBaseLineLayoutExample(props: {}): React.Node {
const texts = [];
for (let i = 9; i >= 0; i--) {
texts.push(
<Text
key={i}
style={{fontSize: 8 + i * 5, maxWidth: 20, backgroundColor: '#eee'}}>
{i}
</Text>,
);
}

const marker = (
<View style={{width: 20, height: 20, backgroundColor: 'gray'}} />
);
const subtitleStyle = {fontSize: 16, marginTop: 8, fontWeight: 'bold'};

return (
<View>
<Text style={subtitleStyle}>{'Nested <Text/>s:'}</Text>
<View style={{flexDirection: 'row', alignItems: 'baseline'}}>
{marker}
<Text>{texts}</Text>
{marker}
</View>

<Text style={subtitleStyle}>{'Array of <Text/>s in <View>:'}</Text>
<View style={{flexDirection: 'row', alignItems: 'baseline'}}>
{marker}
{texts}
{marker}
</View>

<Text style={subtitleStyle}>{'Interleaving <View> and <Text>:'}</Text>
<View style={{flexDirection: 'row', alignItems: 'baseline'}}>
{marker}
<Text selectable={true}>
Some text.
<View
style={{
flexDirection: 'row',
alignItems: 'baseline',
backgroundColor: '#eee',
}}>
{marker}
<Text>Text inside View.</Text>
{marker}
</View>
</Text>
{marker}
</View>
</View>
);
}

exports.title = 'Text';
exports.documentationURL = 'https://reactnative.dev/docs/text';
exports.category = 'Basic';
Expand All @@ -895,4 +951,10 @@ exports.examples = [
return <TextExample />;
},
},
{
title: "Text `alignItems: 'baseline'` style",
render: function(): React.Node {
return <TextBaseLineLayoutExample />;
},
},
];

0 comments on commit 1acf334

Please sign in to comment.