【问题标题】:React native text going off my screen, refusing to wrap. What to do?反应原生文本离开我的屏幕,拒绝换行。该怎么办?
【发布时间】:2016-07-17 00:25:18
【问题描述】:

以下代码可以在this live example找到

我有以下反应原生元素:

'use strict';

var React = require('react-native');
var {
  AppRegistry,
  StyleSheet,
  Text,
  View,
} = React;

var SampleApp = React.createClass({
  render: function() {
    return      (
  <View style={styles.container}>

        <View style={styles.descriptionContainerVer}>
          <View style={styles.descriptionContainerHor}>
            <Text style={styles.descriptionText} numberOfLines={5} >
              Here is a really long text that you can do nothing about, its gonna be long wether you like it or not, so be prepared for it to go off screen. Right? Right..!
            </Text>
          </View>
        </View>

        <View style={styles.descriptionContainerVer2}>
          <View style={styles.descriptionContainerHor}>
            <Text style={styles.descriptionText} numberOfLines={5} >Some other long text which you can still do nothing about.. Off the screen we go then.</Text>
          </View>
        </View>



  </View>);
  }
});
AppRegistry.registerComponent('SampleApp', () => SampleApp);

具有以下样式:

var styles = StyleSheet.create({
  container:{
        flex:1,
    flexDirection:'column',
        justifyContent: 'flex-start',
        backgroundColor: 'grey'
    },
    descriptionContainerVer:{
    flex:0.5, //height (according to its parent)
    flexDirection: 'column', //its children will be in a row
    alignItems: 'center',
    backgroundColor: 'blue',
    // alignSelf: 'center',
  },
  descriptionContainerVer2:{
    flex:0.5, //height (according to its parent)
    flexDirection: 'column', //its children will be in a row
    alignItems: 'center',
    backgroundColor: 'orange',
    // alignSelf: 'center',
  },
  descriptionContainerHor:{
    //width: 200, //I DON\'T want this line here, because I need to support many screen sizes
    flex: 0.3,  //width (according to its parent)
    flexDirection: 'column',    //its children will be in a column
    alignItems: 'center', //align items according to this parent (like setting self align on each item)
    justifyContent: 'center',
    flexWrap: 'wrap'
  },
  descriptionText: {
    backgroundColor: 'green',//Colors.transparentColor,
    fontSize: 16,
    color: 'white',
    textAlign: 'center',
    flexWrap: 'wrap'
  }
});

这将导致以下屏幕:

如何阻止文本离开屏幕并将其限制在屏幕中间,宽度为父级的 80%。

我认为我不应该使用width,因为我将在许多不同的移动屏幕上运行它并且我希望它是动态的,所以我认为我应该完全依赖flexbox

(这就是我在descriptionContainerHor 中包含flex: 0.8 的最初原因。

我想要实现的是这样的:

谢谢!

【问题讨论】:

    标签: css reactjs react-native flexbox


    【解决方案1】:

    我从下面的链接中找到了解决方案。

    [Text] Text doesn't wrap #1438

    <View style={{flexDirection:'row'}}> 
       <Text style={{flex: 1, flexWrap: 'wrap'}}> You miss fdddddd dddddddd 
         You miss fdd
       </Text>
    </View>
    

    如果你想感谢他,下面是 Github 个人资料用户链接。

    Ally Rippley


    编辑:2019 年 4 月 9 日星期二

    正如 @sudoPlz 在 cmets 中提到的,它与 flexShrink: 1 一起更新这个答案。

    【讨论】:

    • 谢谢,这是一个很好的答案,但我已经尝试过了,但由于某种原因它并不总是有效(不知道为什么:S)。 flexWrap 在 react-native 中有点不稳定。 +1 虽然提出这个问题。
    • ^^^ 这是这里的实际答案。接受此操作!
    • 请注意这个答案的信息部分github.com/facebook/react-native/issues/…
    • 我发现在某些情况下flexShrink: 1 应用于父视图也会有所帮助。
    • 我正在处理自定义卡片组件,但这些解决方案不起作用。对我来说,有必要为我的内容容器定义一个恒定的宽度大小(我使用 Dimensions 宽度)。
    【解决方案2】:

    该问题的解决方案是flexShrink: 1

    <View
        style={{ flexDirection: 'row' }}
    > 
       <Text style={{ flexShrink: 1 }}>
           Really really long text...
       </Text>
    </View>
    

    根据您的设置,您可能还需要将 flexShrink: 1 添加到 &lt;View&gt; 的父级,以使其正常工作,所以玩它,您会成功的。

    解决方案是Adam Pietrasiakthis thread.中发现的

    【讨论】:

    • 父视图也是我的解决方案!如果父级有 flexDirection: 'column',则文本拒绝换行。
    • 你刚刚救了我的命……
    【解决方案3】:

    这是a known bugflexWrap: 'wrap' 对我不起作用,但这个解决方案似乎对大多数人都有效

    代码

    <View style={styles.container}>
        <Text>Some text</Text>
    </View>
    

    样式

    export default StyleSheet.create({
        container: {
            width: 0,
            flexGrow: 1,
            flex: 1,
        }
    });
    

    【讨论】:

    • 我花了一天时间才找到你的答案...谢谢!
    • 当单行文本超出绑定时,我的 android 模拟器永远冻结了。找到并修复这是一个可怕的错误(这个不那么相关的 SO 问题是我发现的唯一问题)。这似乎已经修复了它,一个带有 {flexGrow: 1, flex: 1} 的容器和带有 {flex: 1} 的文本。
    【解决方案4】:

    您只需要为您的&lt;Text&gt; 使用如下所示的 flex 包装器;

    <View style={{ flex: 1 }}>
      <Text>Your Text</Text>
    </View>
    

    【讨论】:

    • 这是唯一有效的解决方案
    • 确实,flex: 1 就是你所需要的。
    • 如果您不希望您的文本占据所有可用空间怎么办?
    • 只有 &lt;Text style={{ flex: 1 }}&gt; 没有额外的 &lt;View&gt; 对我也有效。
    【解决方案5】:

    这对我有用

    <View style={{flexShrink:1}}>
      <Text>some long random text...</Text>
    </View>
    

    【讨论】:

      【解决方案6】:

      如果您分别从descriptionContainerVerdescriptionContainerVer2 中删除flexDirection: row,它会起作用。

      更新(见 cmets)

      我进行了一些更改以实现我认为您所追求的目标。首先,我删除了descriptionContainerHor 组件。然后我将垂直视图的flexDirection 设置为row 并添加alignItems: 'center'justifyContent: 'center'。由于现在垂直视图实际上是沿水平轴堆叠的,因此我从名称中删除了 Ver 部分。

      所以现在你有一个包装视图,它应该垂直和水平对齐它的内容并沿 x 轴堆叠它。然后我简单地在Text 组件的左右两侧放了两个不可见的View 组件来做填充。

      像这样:

      <View style={styles.descriptionContainer}>
        <View style={styles.padding}/>
          <Text style={styles.descriptionText} numberOfLines={5} >
            Here is a really long text that you can do nothing about, its gonna be long wether you like it or not, so be prepared for it to go off screen. Right? Right..!
          </Text>
        <View style={styles.padding}/>
      </View>
      

      还有这个:

      descriptionContainer:{
        flex:0.5, //height (according to its parent),
        flexDirection: 'row',
        backgroundColor: 'blue',
        alignItems: 'center',
        justifyContent: 'center',
        // alignSelf: 'center',
      },
      padding: {
        flex: 0.1
      },
      descriptionText: {
        backgroundColor: 'green',//Colors.transparentColor,
        fontSize: 16,
        flex: 0.8,
        color: 'white',
        textAlign: 'center',
        flexWrap: 'wrap'
      },
      

      然后你就会得到我相信你所追求的东西。

      进一步改进

      现在,如果您想在蓝色和橙色视图中堆叠多个文本区域,您可以执行以下操作:

      <View style={styles.descriptionContainer2}>
        <View style={styles.padding}/>
        <View style={styles.textWrap}>
          <Text style={styles.descriptionText} numberOfLines={5} >
            Some other long text which you can still do nothing about.. Off the screen we go then.
          </Text>
          <Text style={styles.descriptionText} numberOfLines={5} >
            Another column of text.
          </Text>
        </View>
        <View style={styles.padding}/>
      </View>
      

      textWrap 的样式如下:

      textWrap: {
        flexDirection: 'column',
        flex: 0.8
      },
      

      希望这会有所帮助!

      【讨论】:

      • 好的,我稍微改变了问题以反映我真正希望实现的目标。现在关于答案:我使用flexDirection: row 的原因是因为(如果我有这个权利)flexDirection 决定了那个父母的“孩子”将被堆叠的方向。现在我希望 text 成为父级中的 middle child,将子级连续堆叠,并占据父级宽度的 80%(类似于第二张照片) .您能否稍微更新一下答案以反映这一点?我愿意接受这个作为答案。
      • 很抱歉回复晚了,一直很忙。但我已经更新了我的答案,希望这是你需要的。
      • 这个答案绝对令人惊叹.. 正是我一直在寻找的,谢谢 Elliot !!!!!!
      • flexDirection: "row" 是我问题的核心,没有运气就尝试了其他所有方法。将您的flexDirection 更改为column,其中的文本将正常换行。
      【解决方案7】:
      <View style={{flexDirection:'row'}}> 
        <Text style={{flex: 1, flexWrap: 'wrap'}}> 
      

      这会起作用

      【讨论】:

      • 不需要Flexwrap。
      【解决方案8】:

      我发现的另一个解决方案是将文本包装在视图中。还将 View 的样式设置为 flex: 1.

      【讨论】:

        【解决方案9】:

        我遇到了同样的问题,为了解决这个问题,我必须确保所有 View 的父母都有 style={{flex: 1}}

        【讨论】:

          【解决方案10】:

          在 React Native 的 0.62.2 版本中,我只是将“flex-shrink: 1”放在“Text”的容器中,但请记住容器视图中的 flex-direction:row。谢谢大家的帮助。

          我的代码:

          export const Product = styled.View`
            background: #fff;
            padding: 15px 10px;
            border-radius: 5px;
            margin: 5px;
            flex-direction: row;
          `;
          
          export const ProductTitleContainer = styled.View`
            font-size: 16px;
            margin-left: 5px;
            flex-shrink: 1;
          `;
          
          export const ProductTitle = styled.Text`
            font-size: 16px;
            flex-wrap: wrap;
          `;
          `;
          

          【讨论】:

            【解决方案11】:

            我想补充一点,我遇到了同样的问题,而 flexWrap, flex:1(在文本组件中),没有任何 flex 对我有用。

            最后,我将文本组件的包装器的宽度设置为设备的宽度,然后文本开始包装。 const win = Dimensions.get('window');

            <View style={{
              flex: 1,
              flexDirection: 'column',
              justifyContent: 'center',
              alignSelf: 'center',
              width: win.width
            }}>
              <Text style={{ top: 0, alignSelf: 'center' }} >{image.title}</Text>
              <Text style={{ alignSelf: 'center' }}>{image.description}</Text>
            </View>
            

            【讨论】:

              【解决方案12】:
              <View style={{flexDirection:'row'}}> 
                 <Text style={{ flex: number }}> You miss fdddddd dddddddd 
                   You miss fdd
                 </Text>
              </View>
              

              { flex: aNumber } 就是你所需要的!

              只需将“flex”设置为适合您的数字即可。然后文本将换行。

              【讨论】:

              • 奇怪的是,这实际上是对我有用的修复程序。
              【解决方案13】:
              <SafeAreaView style={{flex:1}}>
                <View style={{alignItems:'center'}}>
                  <Text style={{ textAlign:'center' }}>
                    This code will make your text centered even when there is a line-break
                  </Text>
                </View>
              </SafeAreaView>
              

              【讨论】:

              • 请评论您的代码并解释您的答案
              【解决方案14】:

              我认为你可以做这样的事情,我附上了一张带有代码的图片以获得更好的想法:

              所以,我们可以这样做:

              TermsOfService = {
                fontFamily: 'Verlag-Book';
                fontSize: 14px;
                textAlign: center;
              },
              HighlightedText = {
                font-family: 'Verlag-Book';
                font-size: 14px;
                text-align: center;
                color: ${COLORS.PRIMARY_ADMIRAL_BLUE};
              },
              Container: {
                width: 100%;
                alignSelf: center;
                alignItems: center;
                justifyContent: center;
                flexDirection: row;
                flexWrap: wrap;
              }
              

              你的组件就是这样使用它吗:

               <View style={Container}>
                 <Text style={TermsOfService}>By joining, you agree to the some thing </Text>
                 <Text style={HighlightedText}>this is highlighted </Text>
                 <Text style={TermsOfService}>and </Text>
                 <Text style={HighlightedText}>and this as well</Text>
               </View>
              

              【讨论】:

                【解决方案15】:

                没有一个答案对我有用,所以我决定使用一种技巧,即用空格分割文本并分别呈现每个单词。

                虽然这是一个 hack,但好处是我不必担心由于父容器样式而弄乱了包装。

                // This code is written in Typescript
                import React from 'react'
                import { StyleSheet, View, Text } from 'react-native'
                const styles = StyleSheet.create({
                  container: {
                    display: 'flex',
                    flexWrap: 'wrap',
                    flexDirection: 'row',
                    flex: 1,
                    justifyContent: 'center',
                    paddingVertical: 8,
                  },
                })
                
                export const WrapText: React.FC<{
                  text: string
                }> = ({ text }) => {
                  return (
                    <View style={styles.container}>
                      {text.split(' ').map((word, index) => (
                          <Text key={index}>
                            {word}{' '}
                          </Text>
                        ))}
                    </View>
                  )
                }
                
                const Example = <WrapText text="Hello this is a working hack that wraps your text."/>
                

                P/S:当然这仅适用于字母书写系统,其他不使用空格的书写系统(例如中文文字)将无法使用此组件进行换行。

                【讨论】:

                  【解决方案16】:

                  不幸的是,上述方法都不适合我。

                  我找到了这个 npm 包,你可以直接使用这个包: https://github.com/Bang9/react-native-wrapped-text

                  或者创建类似这样的东西:

                  <View style={{ alignItems: "center", alignSelf: "center", width: "100%" }}>
                    <View style={{ flexDirection: "row", flexWrap: "wrap"}}>
                      <Text style={{ textAlign: "center"}}>Long text, sooo looong...</Text>
                    </View>
                  </View>
                  

                  基于: https://github.com/Bang9/react-native-wrapped-text/blob/master/src/index.js

                  【讨论】:

                    【解决方案17】:

                    在文本样式中使用 height: 'auto'。

                    【讨论】:

                      【解决方案18】:

                      什么都试过了,除了这个 ->

                      wrapText:{
                          width:"65%"
                      },
                      listItemLeft:{
                          fontWeight:"bold",
                          margin:3
                      },
                      
                      <View style={styles.wrapText}>
                          <Text style={styles.listItemLeft}>{item.left}</Text>
                      </View>
                      

                      【讨论】:

                        【解决方案19】:

                        我尝试了上面的许多答案,但没有一个对我有用。 我通过将flexShrink 放在Text 元素本身上并将flexGrow 放在父ViewText 元素上,获得了最好的结果。

                        我需要父级上的flexDirection: row,因为我想在右侧有一个图标

                        <View style={flexDirection: 'row', flexGrow: 1}>
                            <Text style={
                                flexGrow: 1, 
                                flexShrink: 1, 
                                paddingLeft: 16,
                                paddingRight: 8,
                                alignItems: 'center',
                            }>
                                A long text that needs to wrap into multiple lines
                            </Text>
                        </View>
                        <Image source={rightArrow}/>
                        

                        看起来像这样:

                        【讨论】:

                          【解决方案20】:

                          要将文本换行到下一行而不离开显示,我们可以通过限制&lt;Text&gt;的宽度来做到这一点;

                          <Text style={{width: "60%"}}>some long text goes here ...</Text>
                          

                          上面的代码会将文本的宽度限制为可用宽度的 60%,如果整个文本不适合该宽度,它将自动换行,即剩余的文本将移至下一行,依此类推。

                          【讨论】:

                            【解决方案21】:

                            我的解决方案如下:

                            <View style={style.aboutContent}>
                                 <Text style={[styles.text,{textAlign:'justify'}]}>
                                    // text here                            
                                 </Text>
                            </View>
                            

                            风格:

                            aboutContent:{
                                flex:8,
                                width:widthDevice-40,
                                alignItems:'center'
                            },
                            text:{
                                fontSize:widthDevice*0.04,
                                color:'#fff',
                                fontFamily:'SairaSemiCondensed-Medium'
                            },
                            

                            结果: [

                            【讨论】:

                            • 所以你在父节点上使用了一个静态宽度,这正是我们在这里想要避免的。
                            【解决方案22】:
                            <Text style={{width: 200}} numberOfLines={1} ellipsizeMode="tail">Your text here</Text>
                            

                            【讨论】:

                            • 请描述您的答案的哪一部分解决了 OPs 问题以及原因。
                            猜你喜欢
                            • 2021-02-22
                            • 2019-04-05
                            • 1970-01-01
                            • 1970-01-01
                            • 1970-01-01
                            • 2022-12-11
                            • 2019-06-15
                            • 1970-01-01
                            • 1970-01-01
                            相关资源
                            最近更新 更多