Skip to content

Commit bdc184a

Browse files
Implement adjustsFontSizeToFit on android
1 parent 75a7a52 commit bdc184a

File tree

7 files changed

+286
-88
lines changed

7 files changed

+286
-88
lines changed

RNTester/js/examples/Text/TextExample.android.js

Lines changed: 128 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ const React = require('react');
1616
const TextInlineView = require('../../components/TextInlineView');
1717
const TextLegend = require('../../components/TextLegend');
1818

19-
const {StyleSheet, Text, View} = require('react-native');
19+
const {LayoutAnimation, StyleSheet, Text, View} = require('react-native');
2020

2121
class Entity extends React.Component<{|children: React.Node|}> {
2222
render() {
@@ -70,10 +70,137 @@ class AttributeToggler extends React.Component<{}, $FlowFixMeState> {
7070
}
7171
}
7272

73+
type AdjustingFontSizeProps = $ReadOnly<{||}>;
74+
75+
type AdjustingFontSizeState = {|
76+
dynamicText: string,
77+
shouldRender: boolean,
78+
|};
79+
80+
class AdjustingFontSize extends React.Component<
81+
AdjustingFontSizeProps,
82+
AdjustingFontSizeState,
83+
> {
84+
state = {
85+
dynamicText: '',
86+
shouldRender: true,
87+
};
88+
89+
reset = () => {
90+
LayoutAnimation.easeInEaseOut();
91+
this.setState({
92+
shouldRender: false,
93+
});
94+
setTimeout(() => {
95+
LayoutAnimation.easeInEaseOut();
96+
this.setState({
97+
dynamicText: '',
98+
shouldRender: true,
99+
});
100+
}, 300);
101+
};
102+
103+
addText = () => {
104+
this.setState({
105+
dynamicText:
106+
this.state.dynamicText +
107+
(Math.floor((Math.random() * 10) % 2) ? ' foo' : ' bar'),
108+
});
109+
};
110+
111+
removeText = () => {
112+
this.setState({
113+
dynamicText: this.state.dynamicText.slice(
114+
0,
115+
this.state.dynamicText.length - 4,
116+
),
117+
});
118+
};
119+
120+
render() {
121+
if (!this.state.shouldRender) {
122+
return <View />;
123+
}
124+
return (
125+
<View>
126+
<Text
127+
ellipsizeMode="tail"
128+
numberOfLines={1}
129+
style={{fontSize: 36, marginVertical: 6}}>
130+
Truncated text is baaaaad.
131+
</Text>
132+
<Text
133+
numberOfLines={1}
134+
adjustsFontSizeToFit={true}
135+
style={{fontSize: 40, marginVertical: 6}}>
136+
Shrinking to fit available space is much better!
137+
</Text>
138+
139+
<Text
140+
adjustsFontSizeToFit={true}
141+
numberOfLines={1}
142+
style={{fontSize: 30, marginVertical: 6}}>
143+
{'Add text to me to watch me shrink!' + ' ' + this.state.dynamicText}
144+
</Text>
145+
146+
<Text
147+
adjustsFontSizeToFit={true}
148+
numberOfLines={4}
149+
style={{fontSize: 20, marginVertical: 6}}>
150+
{'Multiline text component shrinking is supported, watch as this reeeeaaaally loooooong teeeeeeext grooooows and then shriiiinks as you add text to me! ioahsdia soady auydoa aoisyd aosdy ' +
151+
' ' +
152+
this.state.dynamicText}
153+
</Text>
154+
155+
<Text
156+
adjustsFontSizeToFit={true}
157+
style={{fontSize: 20, marginVertical: 6, maxHeight: 50}}>
158+
{'Text limited by height, watch as this reeeeaaaally loooooong teeeeeeext grooooows and then shriiiinks as you add text to me! ioahsdia soady auydoa aoisyd aosdy ' +
159+
' ' +
160+
this.state.dynamicText}
161+
</Text>
162+
163+
<Text
164+
adjustsFontSizeToFit={true}
165+
numberOfLines={1}
166+
style={{marginVertical: 6}}>
167+
<Text style={{fontSize: 14}}>
168+
{'Differently sized nested elements will shrink together. '}
169+
</Text>
170+
<Text style={{fontSize: 20}}>
171+
{'LARGE TEXT! ' + this.state.dynamicText}
172+
</Text>
173+
</Text>
174+
175+
<View
176+
style={{
177+
flexDirection: 'row',
178+
justifyContent: 'space-around',
179+
marginTop: 5,
180+
marginVertical: 6,
181+
}}>
182+
<Text style={{backgroundColor: '#ffaaaa'}} onPress={this.reset}>
183+
Reset
184+
</Text>
185+
<Text style={{backgroundColor: '#aaaaff'}} onPress={this.removeText}>
186+
Remove Text
187+
</Text>
188+
<Text style={{backgroundColor: '#aaffaa'}} onPress={this.addText}>
189+
Add Text
190+
</Text>
191+
</View>
192+
</View>
193+
);
194+
}
195+
}
196+
73197
class TextExample extends React.Component<{}> {
74198
render(): React.Node {
75199
return (
76200
<RNTesterPage title="<Text>">
201+
<RNTesterBlock title="Dynamic Font Size Adjustment">
202+
<AdjustingFontSize />
203+
</RNTesterBlock>
77204
<RNTesterBlock title="Wrap">
78205
<Text>
79206
The text should wrap if it goes on multiple lines. See, this is

RNTester/js/examples/Text/TextExample.ios.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,14 @@ class AdjustingFontSize extends React.Component<
222222
this.state.dynamicText}
223223
</Text>
224224

225+
<Text
226+
adjustsFontSizeToFit={true}
227+
style={{fontSize: 20, marginVertical: 6, maxHeight: 50}}>
228+
{'Text limited by height, watch as this reeeeaaaally loooooong teeeeeeext grooooows and then shriiiinks as you add text to me! ioahsdia soady auydoa aoisyd aosdy ' +
229+
' ' +
230+
this.state.dynamicText}
231+
</Text>
232+
225233
<Text
226234
adjustsFontSizeToFit={true}
227235
numberOfLines={1}

ReactAndroid/src/main/java/com/facebook/react/uimanager/ViewProps.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,8 @@ public class ViewProps {
8888
public static final String NEEDS_OFFSCREEN_ALPHA_COMPOSITING = "needsOffscreenAlphaCompositing";
8989
public static final String NUMBER_OF_LINES = "numberOfLines";
9090
public static final String ELLIPSIZE_MODE = "ellipsizeMode";
91+
public static final String ADJUSTS_FONT_SIZE_TO_FIT = "adjustsFontSizeToFit";
92+
public static final String MINIMUM_FONT_SCALE = "minimumFontScale";
9193
public static final String ON = "on";
9294
public static final String RESIZE_MODE = "resizeMode";
9395
public static final String RESIZE_METHOD = "resizeMethod";

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

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -332,7 +332,6 @@ private static int parseNumericFontWeight(String fontWeightString) {
332332
(Build.VERSION.SDK_INT < Build.VERSION_CODES.M) ? 0 : Layout.HYPHENATION_FREQUENCY_NONE;
333333
protected int mJustificationMode =
334334
(Build.VERSION.SDK_INT < Build.VERSION_CODES.O) ? 0 : Layout.JUSTIFICATION_MODE_NONE;
335-
protected TextTransform mTextTransform = TextTransform.UNSET;
336335

337336
protected float mTextShadowOffsetDx = 0;
338337
protected float mTextShadowOffsetDy = 0;
@@ -342,6 +341,8 @@ private static int parseNumericFontWeight(String fontWeightString) {
342341
protected boolean mIsUnderlineTextDecorationSet = false;
343342
protected boolean mIsLineThroughTextDecorationSet = false;
344343
protected boolean mIncludeFontPadding = true;
344+
protected boolean mAdjustsFontSizeToFit = false;
345+
protected float mMinimumFontScale = 0;
345346

346347
/**
347348
* mFontStyle can be {@link Typeface#NORMAL} or {@link Typeface#ITALIC}. mFontWeight can be {@link
@@ -622,4 +623,20 @@ public void setTextTransform(@Nullable String textTransform) {
622623
}
623624
markUpdated();
624625
}
626+
627+
@ReactProp(name = ViewProps.ADJUSTS_FONT_SIZE_TO_FIT)
628+
public void setAdjustFontSizeToFit(boolean adjustsFontSizeToFit) {
629+
if (adjustsFontSizeToFit != mAdjustsFontSizeToFit) {
630+
mAdjustsFontSizeToFit = adjustsFontSizeToFit;
631+
markUpdated();
632+
}
633+
}
634+
635+
@ReactProp(name = ViewProps.MINIMUM_FONT_SCALE)
636+
public void setMinimumFontScale(float minimumFontScale) {
637+
if (minimumFontScale != mMinimumFontScale) {
638+
mMinimumFontScale = minimumFontScale;
639+
markUpdated();
640+
}
641+
}
625642
}

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,11 @@ public void setEllipsizeMode(ReactTextView view, @Nullable String ellipsizeMode)
5959
}
6060
}
6161

62+
@ReactProp(name = ViewProps.ADJUSTS_FONT_SIZE_TO_FIT)
63+
public void setAdjustFontSizeToFit(ReactTextView view, boolean adjustsFontSizeToFit) {
64+
view.setAdjustFontSizeToFit(adjustsFontSizeToFit);
65+
}
66+
6267
@ReactProp(name = ViewProps.TEXT_ALIGN_VERTICAL)
6368
public void setTextAlignVertical(ReactTextView view, @Nullable String textAlignVertical) {
6469
if (textAlignVertical == null || "auto".equals(textAlignVertical)) {

0 commit comments

Comments
 (0)