React Native的Text

用于显示文本的React组件。 文本支持嵌套,样式和触摸处理。 在以下示例中,嵌套标题和正文文本将从styles.baseText继承fontFamily,但标题提供了自己的附加样式。 标题和主体将叠加在一起,因为文字换行:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import React, { Component } from 'react';
import { AppRegistry, Text, StyleSheet } from 'react-native';

class TextInANest extends Component {
  constructor(props) {
    super(props);
    this.state = {
      titleText: "Bird's Nestaaa",
      bodyText: 'This is not really a bird nest.'
    };
  }

  render() {
    return (
      <Text style={styles.baseText}>
        <Text style={styles.titleText} onPress={this.onPressTitle}>
          {this.state.titleText}{'\n'}{'\n'}
        </Text>
        <Text numberOfLines={5}>
          {this.state.bodyText}
        </Text>
      </Text>
    );
  }
}

const styles = StyleSheet.create({
  baseText: {
    fontFamily: 'Cochin',
  },
  titleText: {
    fontSize: 20,
    fontWeight: 'bold',
  },
});

// App registration and rendering
AppRegistry.registerComponent('TextInANest', () => TextInANest);

处理文本输入

TextInput是一个基本组件,允许用户输入文本。 它有一个onChangeText prop,它接受一个函数,每次文本改变时被调用,和一个onSubmitEditing prop,当一个函数被提交时被调用。 例如,让我们说,当用户键入时,您将他们的词翻译成不同的语言。 在这种新语言中,每个单词的写法都是一样的:🍕。 所以句子“Hello there Bob”将翻译为“🍕🍕🍕”。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import React, { Component } from 'react';
import { AppRegistry, Text, TextInput, View } from 'react-native';

class PizzaTranslator extends Component {
  constructor(props) {
    super(props);
    this.state = {text: ''};
  }

  render() {
    return (
      <View style=>
        <TextInput
          style=
          placeholder="Type here to translate!"
          onChangeText={(text) => this.setState({text})}
        />
        <Text style=>
          {this.state.text.split(' ').map((word) => word && '🍕').join(' ')}
        </Text>
      </View>
    );
  }
}

AppRegistry.registerComponent('PizzaTranslator', () => PizzaTranslator);
在这个例子中,我们将文本存储在状态中,因为它随时间而变化。 还有很多事情你可能想做一个文本输入。 例如,您可以在用户键入时验证内部的文本。 有关更多详细示例,请参阅受控组件上的React文档,或TextInput的参考文档。 文本输入可能是其状态随时间自然改变的组件的最简单的示例。

嵌套文本

iOS和Android都允许通过使用粗体或彩色文本(在iOS上为NSAttributedString,Android上为SpannableString)等特定格式设置字符串的范围来显示格式化的文本。 在实践中,这是非常乏味。 对于React Native,我们决定使用Web范例,在这里你可以嵌套文本来实现相同的效果。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import React, { Component } from 'react';
import { AppRegistry, Text } from 'react-native';

class BoldAndBeautiful extends Component {
  render() {
    return (
      <Text style=>
        I am bold
        <Text style=>
          and red
        </Text>
      </Text>
    );
  }
}

AppRegistry.registerComponent('BoldAndBeautiful', () => BoldAndBeautiful);
在幕后,React Native将其转换为包含以下信息的平面NSAttributedString或SpannableString:
1
2
3
"I am bold and red"
0-9: bold
9-17: bold, red

嵌套视图(仅限iOS)

在iOS上,您可以在文本组件中嵌套视图。 这里有一个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import React, { Component } from 'react';
import { AppRegistry, Text, View } from 'react-native';

class BlueIsCool extends Component {
  render() {
    return (
      <Text>
        There is a blue square
        <View style= />
        in between my text.
      </Text>
    );
  }
}

AppRegistry.registerComponent('BlueIsCool', () => BlueIsCool);
为了使用此功能,您必须给视图一个宽度和高度。

容器

元素相对于布局是特殊的:内部的一切不再使用flexbox布局,而是使用文本布局。 这意味着中的元素不再是矩形,而是当它们看到行的末尾时换行。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<Text>
  <Text>First part and </Text>
  <Text>second part</Text>
</Text>
// Text container: all the text flows as if it was one
// |First part |
// |and second |
// |part       |

<View>
  <Text>First part and </Text>
  <Text>second part</Text>
</View>
// View container: each text is its own block
// |First part |
// |and        |
// |second part|

有限样式继承

在网络上,设置整个文档的字体系列和大小的通常方法是写:

1
2
3
4
5
6
/* CSS, *not* React Native */
html {
  font-family: 'lucida grande', tahoma, verdana, arial, sans-serif;
  font-size: 11px;
  color: #141823;
}
当浏览器试图渲染文本节点时,它将一直到树的根元素,并找到一个具有font-size属性的元素。 这个系统的一个意想不到的属性是任何节点都可以有font-size属性,包括一个
。 这是为了方便,即使不是真的语义正确。 在React Native中,我们对它更严格:你必须将所有的文本节点包装在组件内; 您不能在下直接放置文本节点。
1
2
3
4
5
6
7
8
9
10
11
// BAD: will raise exception, can't have a text node as child of a <View>
<View>
  Some text
</View>

// GOOD
<View>
  <Text>
    Some text
  </Text>
</View>
您还失去为整个子树设置默认字体的能力。 在应用程序中使用一致的字体和大小的建议方法是创建一个包含它们的组件MyAppText,并在整个应用程序中使用此组件。 您还可以使用此组件为其他类型的文本创建更具体的组件,如MyAppHeaderText。
1
2
3
4
<View>
  <MyAppText>Text styled with the default font for the entire application</MyAppText>
  <MyAppHeaderText>Text styled as a header</MyAppHeaderText>
</View>
假设MyAppText是一个通过样式简单地将其子代渲染为Text组件的组件,则MyAppHeaderText可以定义如下:
1
2
3
4
5
6
7
8
9
class MyAppHeaderText extends Component {
  render() {
    <MyAppText>
      <Text style=>
        {this.props.children}
      </Text>
    </MyAppText>
  }
}
以这种方式组合MyAppText确保我们从顶级组件获取样式,但让我们能够在特定用例中添加/覆盖它们。 React Native仍然具有样式继承的概念,但仅限于文本子树。 在这种情况下,第二部分将是粗体和红色。
1
2
3
4
5
6
<Text style=>
  I am bold
  <Text style=>
    and red
  </Text>
</Text>
我们相信,这种更受限制的样式文本的方式将产生更好的应用程序:
  • (开发者)React组件的设计考虑了强烈的隔离:你应该能够在应用程序的任何地方放置一个组件,相信只要props是相同的,它将看起来和行为相同的方式。 可以从props外继承的文本属性会破坏这种隔离。
  • (实现者)React Native的实现也被简化。 我们不需要在每个单个元素上都有一个fontFamily字段,并且我们不需要在每次显示文本节点时都将树遍历到根。 样式继承仅在原生Text组件内编码,不会泄漏到其他组件或系统本身。

Comments