Reação de texto nativo saindo da minha tela, recusando-se a embrulhar. O que fazer?


122

O código a seguir pode ser encontrado neste exemplo ao vivo

Eu tenho o seguinte elemento nativo reac:

'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);

com os seguintes estilos:

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'
  }
});

Isso resulta na seguinte tela:

Aplicativo de texto fora da tela

Como posso impedir que o texto saia da tela e mantê-lo confinado no meio da tela com uma largura de, por exemplo, 80% do pai.

Não acho que devo usar widthporque estarei executando em MUITAS telas diferentes de dispositivos móveis e quero que seja dinâmico, então acho que devo confiar totalmente flexbox.

(Essa foi a razão inicial pela qual eu tive flex: 0.8dentro do descriptionContainerHor.

O que eu quero alcançar é algo assim:

O que eu quero alcançar

Obrigado!

Respostas:


206

Eu encontrei solução no link abaixo.

[Texto] O texto não quebra # 1438

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

Resultado

Abaixo está o link de usuário do perfil do Github se você quiser agradecê-lo.

Ally Rippley


Edit: Ter 09 de abril de 2019

Como @sudoPlz mencionou nos comentários, ele flexShrink: 1atualiza esta resposta.

insira a descrição da imagem aqui


1
Obrigado, é uma ótima resposta, mas eu tentei e por algum motivo nem sempre funciona (não tenho ideia por que: S). flexWrap é um pouco fragmentado em reagente nativo. 1 embora por trazer isso à tona.
SudoPlz

1
^^^ Esta é a resposta real aqui. Aceite esta Op!
Greg Blass

1
Observe a parte de informações desta resposta github.com/facebook/react-native/issues/…
SudoPlz

12
Descobri que, em alguns casos, flexShrink: 1aplicado à visão pai também ajudará.
SudoPlz

Isso funciona. Obrigado.
Uddesh_jain

68

Este é um bug conhecido . flexWrap: 'wrap'não funcionou para mim, mas esta solução parece funcionar para a maioria das pessoas

Código

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

Estilos

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

1
só levei um dia para encontrar sua resposta ... Obrigado!
Kevin Amiranoff

63

A solução para esse problema é flexShrink: 1.

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

Dependendo de sua configuração, você também pode precisar adicionar flexShrink: 1ao <View>pai de também, para fazer isso funcionar, então brinque com isso e você vai conseguir.

A solução foi descoberta por Adam Pietrasiak em esta discussão.


A visão dos pais também foi a solução para mim! Se o pai tivesse flexDirection: 'coluna', o texto se recusava a quebrar.
crestinglight

1
Você acabou de salvar minha vida ...
Nikandr Marhal

Funcionou perfeitamente, obrigado!
fadzb

31

você só precisa ter um invólucro para seu <Text>com flex como abaixo;

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

2
Essa é a única solução adequada que realmente funciona bem
AlwaysConfused de

2
Na verdade, flex: 1é tudo que você precisa.
instância de

10

Funciona se você remover flexDirection: rowde descriptionContainerVere descriptionContainerVer2respectivamente.

ATUALIZAÇÃO (ver comentários)

Fiz algumas alterações para alcançar o que acho que você quer. Em primeiro lugar, removi o descriptionContainerHorcomponente. Em seguida, defini as flexDirectionvisualizações verticais como rowe adicionei alignItems: 'center'e justifyContent: 'center'. Uma vez que as vistas verticais estão agora empilhadas ao longo do eixo horizontal, removi oVer parte do nome.

Portanto, agora você tem uma visualização de wrapper que deve alinhar vertical e horizontalmente seu conteúdo e empilhá-lo ao longo do eixo x. Em seguida, simplesmente coloco dois Viewcomponentes invisíveis no lado esquerdo e direito do Textcomponente para fazer o preenchimento.

Como isso:

<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>

E isto:

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'
},

Então você consegue o que eu acredito que você estava procurando.

OUTRAS MELHORIAS

Agora, se você gostaria de empilhar várias áreas de texto dentro das visualizações azul e laranja, você pode fazer algo assim:

<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>

Onde textWrapé estilizado assim:

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

Espero que isto ajude!


Ok, mudei um pouco a pergunta para refletir o que realmente desejo alcançar. Agora sobre a resposta: O motivo que usei flexDirection: rowfoi porque (se é que estou bem na minha cabeça) flexDirectiondita a direção em que os 'filhos' desse pai serão empilhados. Agora eu queria que o texto fosse o filho do meio em um pai que empilha os filhos em uma fileira e ocupasse 80% da largura dos pais (algo como a segunda foto). Você poderia atualizar um pouco a resposta para refletir isso? Estou disposto a aceitar isso como a resposta.
SudoPlz

Desculpe pelo atraso na resposta, estou ocupado. Mas eu atualizei minha resposta, espero que seja isso que você precisava.
Eysi

Esta resposta é ABSOLUTAMENTE incrível .. Exatamente o que eu estava procurando, obrigado Elliot !!!!!
SudoPlz

flexDirection: "row"foi o cerne do meu problema, tentei de tudo sem sorte. Altere seu flexDirectionpara columne o texto dentro dele será quebrado normalmente.
oitenta

8

Outra solução que encontrei para esse problema é envolver o Texto dentro de uma Visualização. Defina também o estilo da vista para flex: 1.


2

Queria acrescentar que estava tendo o mesmo problema e flexWrap, flex: 1 (nos componentes de texto), nada do flex estava funcionando para mim.

Eventualmente, eu defini a largura do invólucro dos meus componentes de texto para a largura do dispositivo e o texto começou a ser agrupado. 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>

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

{flex: aNumber} é tudo que você precisa!

Basta definir 'flex' para um número adequado para você. E então o texto será quebrado.


Estranhamente, essa foi a solução que funcionou para mim.
Dror Bar

1

Na versão 0.62.2 do React Native, eu apenas coloquei "flex-shrink: 1" no Container do meu "Text", mas lembre-se do flex-direction: row na visualização do container. Obrigado a vocês pela ajuda.

Meu código:

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;
`;
`;

-1

minha solução abaixo:

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

estilo:

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

resultado: [d] meu resultado [1]


Portanto, você está usando uma largura estática no pai, que é exatamente o que queríamos evitar aqui.
SudoPlz

-1
<Text style={{width: 200}} numberOfLines={1} ellipsizeMode="tail">Your text here</Text>

Descreva que parte de sua resposta resolve os problemas de OPs e por quê.
Sebastian B.
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.