React Native不支持CSS display
属性,默认情况下,所有元素都使用display: flex
的行为(无inline-flex
)。大多数非flex布局都可以使用flex属性进行模拟,但是我对内联文本感到慌乱。
我的应用有一个容器,其中包含几个文字,其中一些需要格式化。这意味着我需要使用跨度来完成格式化。为了实现跨度的包装,我可以将容器设置为使用flex-wrap: wrap
,但这只允许在跨度结束时换行,而不是在换行符时包装的传统内联行为。
问题可视化(以黄色显示):
(通过http://codepen.io/anon/pen/GoWmdm?editors=110)
有没有办法使用flex属性进行正确的包装和真正的内联模拟?
答案 0 :(得分:65)
您可以通过将文本元素包装在div或其他元素中的span的方式来包装其他文本元素来获得此效果:
<View>
<Text><Text>This writing should fill most of the container </Text><Text>This writing should fill most of the container</Text></Text>
</View>
您也可以通过声明flexDirection来获得此效果:&#39; row&#39;父母的属性以及flexWrap:&#39; wrap&#39;。然后孩子们将显示内联:
<View style={{flexDirection:'row', flexWrap:'wrap'}}>
<Text>one</Text><Text>two</Text><Text>Three</Text><Text>Four</Text><Text>Five</Text>
</View>
查看this示例。
答案 1 :(得分:3)
我还没有找到与其他内容嵌入文本块的正确方法。我们当前的“hackish”解决方法是将文本字符串中的每个单词拆分为自己的块,以便flexWrap为每个单词正确包装。
答案 2 :(得分:3)
您只能嵌套文本节点,而不能使用flex获得所需的效果。 像这样:https://facebook.github.io/react-native/docs/text
<Text style={{fontWeight: 'bold'}}>
I am bold
<Text style={{color: 'red'}}>
and red
</Text>
</Text>
答案 3 :(得分:1)
我有以下用例:
我需要一个可以用不同大小包裹的文本,并且在整个文本中,我都想强调一些单词(以表示它们是可单击的)。
很简单的情况是,您无法以任何方式控制下划线(它的接近程度,颜色是什么,等等)-这使我穿过了兔子洞,最终想到了拆分每个单词并将其包装在单独的Text组件中(用View包裹)的解决方案。
我将代码粘贴到这里:
import React from 'react';
import { StyleSheet, View, TouchableOpacity, Text } from 'react-native';
import Colors from '../../styles/Colors';
import Fonts from '../../styles/Fonts';
const styles = StyleSheet.create({
container: {
flex: 1,
},
});
export default class SaltText extends React.Component {
getTheme (type) {
if (type === 'robomonoregular10gray') {
return {
fontSize: Fonts.SIZES.TEN,
fontFamily: Fonts.ROBOTOMONO_REGULAR,
color: Colors.getColorOpacity(Colors.GRAY, 70),
lineHeight: Fonts.SIZES.TEN + 10
};
}
throw new Error('not supported');
}
splitText (text) {
const parts = [];
const maps = [];
let currentPart = '';
let matchIndex = 0;
for (const letter of text) {
const isOpening = letter === '[';
const isClosing = letter === ']';
if (!isOpening && !isClosing) {
currentPart += letter;
continue;
}
if (isOpening) {
parts.push(currentPart);
currentPart = '';
}
if (isClosing) {
parts.push(`[${matchIndex}]`);
maps.push(currentPart);
currentPart = '';
matchIndex++;
}
}
const partsModified = [];
for (const part of parts) {
const splitted = part
.split(' ')
.filter(f => f.length);
partsModified.push(...splitted);
}
return { parts: partsModified, maps };
}
render () {
const textProps = this.getTheme(this.props.type);
const children = this.props.children;
const getTextStyle = () => {
return {
...textProps,
};
};
const getTextUnderlineStyle = () => {
return {
...textProps,
borderBottomWidth: 1,
borderColor: textProps.color
};
};
const getViewStyle = () => {
return {
flexDirection: 'row',
flexWrap: 'wrap',
};
};
const { parts, maps } = this.splitText(children);
return (
<View style={getViewStyle()}>
{parts.map((part, index) => {
const key = `${part}_${index}`;
const isLast = parts.length === index + 1;
if (part[0] === '[') {
const mapIndex = part.substring(1, part.length - 1);
const val = maps[mapIndex];
const onPressHandler = () => {
this.props.onPress(parseInt(mapIndex, 10));
};
return (
<View key={key} style={getTextUnderlineStyle()}>
<Text style={getTextStyle()} onPress={() => onPressHandler()}>
{val}{isLast ? '' : ' '}
</Text>
</View>
);
}
return (
<Text key={key} style={getTextStyle()}>
{part}{isLast ? '' : ' '}
</Text>
);
})}
</View>
);
}
}
和用法:
renderPrivacy () {
const openTermsOfService = () => {
Linking.openURL('https://reactnativecode.com');
};
const openPrivacyPolicy = () => {
Linking.openURL('https://reactnativecode.com');
};
const onUrlClick = (index) => {
if (index === 0) {
openTermsOfService();
}
if (index === 1) {
openPrivacyPolicy();
}
};
return (
<SaltText type="robomonoregular10gray" onPress={(index) => onUrlClick(index)}>
By tapping Create an account or Continue, I agree to SALT\'s [Terms of Service] and [Privacy Policy]
</SaltText>
);
}
这是最终结果:
答案 4 :(得分:1)
试试这个,简单又干净。
<Text style={{ fontFamily: 'CUSTOM_FONT', ... }}>
<Text>Lorem ipsum</Text>
<Text style={{ color: "red" }}> dolor sit amet.</Text>
</Text>
结果:
Lorem ipsum dolor sit amet.