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!

SudoPlz
fonte

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

Ashok R
fonte
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,
    }
});
Dev01
fonte
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.

SudoPlz
fonte
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>
jsina
fonte
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!

Eysi
fonte
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.

Joel
fonte
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>
mcc
fonte
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.

letanthang
fonte
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;
`;
`;
Marcelo Tchelão
fonte
-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]

Nguyễn Phúc
fonte
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>
Saurav
fonte
Descreva que parte de sua resposta resolve os problemas de OPs e por quê.
Sebastian B.