web-dev-qa-db-fra.com

Réagis texte sortant de mon écran, refusant de boucler. Que faire?

Le code suivant peut être trouvé dans cet exemple live

J'ai l'élément réactif natif suivant:

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

avec les styles suivants:

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

Cela se traduit par l'écran suivant: 

 Text off screen app

Comment puis-je empêcher le texte de sortir de l’écran et le maintenir confiné au milieu de l’écran avec une largeur égale à 80% du parent? 

Je ne pense pas que je devrais utiliser width car je vais l'exécuter sur BEAUCOUP d'écrans mobiles différents et je veux que ce soit dynamique. Je pense donc que je devrais me fier totalement à flexbox

(C’était la raison initiale pour laquelle j’avais flex: 0.8 dans la descriptionContainerHor.

Ce que je veux réaliser ressemble à ceci:

 What I want to achieve

Je vous remercie!

44
SudoPlz

J'ai trouvé la solution à partir du lien ci-dessous.

[Texte] Le texte n'est pas enveloppé # 1438

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

 Output

Voici le lien utilisateur du profil Github si vous voulez le remercier.

Ally Rippley

68
Ashok R

C'est un bug connu . flexWrap: 'wrap' n'a pas fonctionné pour moi mais cette solution semble fonctionner pour la plupart des gens

Code

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

Modes

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

Cela fonctionne si vous supprimez flexDirection: row de descriptionContainerVer et descriptionContainerVer2 respectivement.

MISE À JOUR (voir commentaires)

J'ai fait quelques changements pour réaliser ce que je pense que vous recherchez. Tout d'abord, j'ai supprimé le composant descriptionContainerHor. Ensuite, je règle la flexDirection des vues verticales sur row et ajoute alignItems: 'center' et justifyContent: 'center'. Puisque les vues verticales sont maintenant empilées le long de l'axe horizontal, j'ai supprimé la partie Ver du nom.

Vous avez maintenant une vue wrapper qui doit aligner son contenu verticalement et horizontalement et l’empiler le long de l’axe des x. Ensuite, j'ai simplement placé deux composants View invisibles à gauche et à droite du composant Text pour effectuer le remplissage.

Comme ça: 

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

Et ça:

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

Ensuite, vous obtenez ce que je crois que vous étiez après.

AUTRES AMÉLIORATIONS

Maintenant, si vous souhaitez empiler plusieurs zones de texte dans les vues bleue et orange, vous pouvez faire quelque chose comme ceci:

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

textWrapest stylé comme ceci:

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

J'espère que cela t'aides!

8
Eysi

vous avez juste besoin d’un wrapper pour votre <Text> avec flex comme ci-dessous;

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

Une autre solution que j'ai trouvée à ce problème consiste à envelopper le texte dans une vue. Définissez également le style de la vue sur flex: 1.

3
Joel

La solution à ce problème est flexShrink: 1.

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

Selon votre configuration, vous devrez peut-être aussi ajouter flexShrink: 1 au parent de <View> pour que cela fonctionne, alors jouez avec cela et vous le ferez.

La solution a été découverte par Adam Pietrasiak dans ce fil.

2
SudoPlz

Cela a fonctionné pour moi dans la plupart des cas, même avec des colonnes flexibles:

wordWrap: 'break-Word'

De cette façon, le texte sera toujours renvoyé à la ligne même avec une largeur codée en dur sur le même élément/composant.

width: 100

Dans ton cas:

width: '80%'

Dans mon cas, il était essentiel de conserver 3 colonnes et de lire le texte.

J'espère que cela t'aides!

0
jasonleonhard