Rendre la vue 80% de la largeur du parent dans React Native


98

Je crée un formulaire dans React Native et je voudrais rendre mon TextInputs 80% de la largeur de l'écran.

Avec HTML et CSS ordinaire, ce serait simple:

input {
    display: block;
    width: 80%;
    margin: auto;
}

Sauf que React Native ne prend pas en charge la displaypropriété, les largeurs en pourcentage ou les marges automatiques.

Alors, que dois-je faire à la place? Il y a une discussion sur ce problème dans le suivi des problèmes de React Native, mais les solutions proposées semblent être de vilains hacks.


1
react-nativeutilise flexpour les tailles et les positions des éléments. Je ne suis pas sûr mais c'est peut-être flex-basisce dont vous avez besoin: Vérifiez ceci et cela
alix

1
Et selon ce problème, quelque chose comme flex: 0.8peut faire le travail.
alix

Réponses:


83

À partir de React Native 0.42 height:et width:accepter les pourcentages.

Utilisez width: 80%dans vos feuilles de style et cela fonctionne.

  • Capture d'écran

  • Exemple en direct
    Largeur / hauteur de l'enfant en proportion du parent

  • Code

    import React from 'react';
    import { Text, View, StyleSheet } from 'react-native';
    
    const width_proportion = '80%';
    const height_proportion = '40%';
    
    const styles = StyleSheet.create({
      screen: {
        flex: 1,
        alignItems: 'center',
        justifyContent: 'center',
        backgroundColor: '#5A9BD4',
      },
      box: {
        width: width_proportion,
        height: height_proportion,
        alignItems: 'center',
        justifyContent: 'center',
        backgroundColor: '#B8D2EC',
      },
      text: {
        fontSize: 18,
      },
    });
    
    export default () => (
      <View style={styles.screen}>
        <View style={styles.box}>
          <Text style={styles.text}>
            {width_proportion} of width{'\n'}
            {height_proportion} of height
          </Text>
        </View>
      </View>
    );

88

Cela devrait répondre à vos besoins:

var yourComponent = React.createClass({
    render: function () {
        return (
            <View style={{flex:1, flexDirection:'column', justifyContent:'center'}}>
                <View style={{flexDirection:'row'}}>
                    <TextInput style={{flex:0.8, borderWidth:1, height:20}}></TextInput>
                    <View style={{flex:0.2}}></View> // spacer
                </View>
            </View>
        );
    }
});

17
juste <View style = {{width: '75% ', borderWidth: 1}}> </View>
user3044484

41

Si vous cherchez simplement à rendre l'entrée relative à la largeur de l'écran, un moyen simple serait d'utiliser Dimensions:

// De structure Dimensions from React
var React = require('react-native');
var {
  ...
  Dimensions
} = React; 

// Store width in variable
var width = Dimensions.get('window').width; 

// Use width variable in style declaration
<TextInput style={{ width: width * .8 }} />

J'ai mis en place un projet de travail ici . Le code est également ci-dessous.

https://rnplay.org/apps/rqQPCQ

'use strict';

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

var width = Dimensions.get('window').width;

var SampleApp = React.createClass({
  render: function() {
    return (
      <View style={styles.container}>
        <Text style={{fontSize:22}}>Percentage Width In React Native</Text>
        <View style={{marginTop:100, flexDirection: 'row',justifyContent: 'center'}}>
            <TextInput style={{backgroundColor: '#dddddd', height: 60, width: width*.8 }} />
          </View>
      </View>
    );
  }
});

var styles = StyleSheet.create({
  container: {
    flex: 1,
    marginTop:100
  },

});

AppRegistry.registerComponent('SampleApp', () => SampleApp);

6
Les documents React Native devraient mentionner le package Dimensions sur la première page - que cela ne m'étonne pas ...
AA Karim

réponse très précieuse. Les dimensions sont en fait très utiles. Remarque: «Bien que les dimensions soient disponibles immédiatement, elles peuvent changer (par exemple en raison de la rotation de l'appareil), donc toute logique de rendu ou styles qui dépendent de ces constantes doivent essayer d'appeler cette fonction sur chaque rendu, plutôt que de mettre en cache la valeur (par exemple, en utilisant styles en ligne plutôt que de définir une valeur dans une feuille de style). "
phil

Notez que l'utilisation de Dimensions interrompt vos mises en page après la rotation de l'écran si vous prenez en charge le paysage et ne gérez pas ces modifications de mise en page manuellement.
ratsimihah

22

Dans votre StyleSheet, mettez simplement:

width: '80%';

au lieu de:

width: 80%;

Continuez à coder ........ :)


13

Vous pouvez également essayer la feuille de style react-native-extended-style qui prend en charge le pourcentage pour les applications à orientation unique:

import EStyleSheet from 'react-native-extended-stylesheet';

const styles = EStyleSheet.create({
  column: {
    width: '80%',
    height: '50%',
    marginLeft: '10%'
  }
});

5

La technique que j'utilise pour avoir un pourcentage de largeur du parent ajoute une vue d'espacement supplémentaire en combinaison avec une flexbox. Cela ne s'appliquera pas à tous les scénarios, mais cela peut être très utile.

Alors on y va:

class PercentageWidth extends Component {
    render() {
        return (
            <View style={styles.container}>
                <View style={styles.percentageWidthView}>
                    {/* Some content */}
                </View>

                <View style={styles.spacer}
                </View>
            </View>
        );
    }
}

const styles = StyleSheet.create({
    container: {
        flexDirection: 'row'
    },

    percentageWidthView: {
        flex: 60
    },

    spacer: {
        flex: 40
    }
});

Fondamentalement, la propriété flex est la largeur par rapport au flex "total" de tous les éléments du conteneur flex. Donc, si tous les éléments totalisent 100, vous avez un pourcentage. Dans l'exemple, j'aurais pu utiliser les valeurs de flex 6 et 4 pour le même résultat, donc c'est encore plus FLEXible.

Si vous souhaitez centrer la vue en pourcentage de largeur: ajoutez deux entretoises avec la moitié de la largeur. Donc, dans l'exemple, ce serait 2-6-2.

Bien sûr, ajouter des vues supplémentaires n'est pas la chose la plus agréable au monde, mais dans une application du monde réel, je peux imaginer que l'espaceur contiendra un contenu différent.


vous pouvez imaginer que l'espaceur contiendra un contenu différent? Pourquoi? Je peux penser à de nombreux exemples où un espaceur est juste du html de remplissage.
AlxVallejo

1

J'ai une solution mise à jour (fin 2019), pour obtenir une largeur de 80% du parent de manière réactive avec Hooks, cela fonctionne même si l'appareil tourne.

Vous pouvez utiliser Dimensions.get('window').widthpour obtenir la largeur de l'appareil dans cet exemple, vous pouvez voir comment vous pouvez le faire de manière réactive

import React, { useEffect, useState } from 'react';
import { Dimensions , View , Text , StyleSheet  } from 'react-native';

export default const AwesomeProject() => {
   const [screenData, setScreenData] = useState(Dimensions.get('window').width);

    useEffect(() => {
     const onChange = () => {
     setScreenData(Dimensions.get('window').width);
     };
     Dimensions.addEventListener('change', onChange);

     return () => {Dimensions.removeEventListener('change', onChange);};
    });

   return (  
          <View style={[styles.container, { width: screenData * 0.8 }]}>
             <Text> I'mAwesome </Text>
           </View>
    );
}

const styles = StyleSheet.create({
container: {
     flex: 1,
     alignItems: 'center',
     justifyContent: 'center',
     backgroundColor: '#eee',
     },
});

0

C'est ainsi que j'ai trouvé la solution. Simple et doux. Indépendant de la densité de l'écran:

export default class AwesomeProject extends Component {
    constructor(props){
        super(props);
        this.state = {text: ""}
    }
  render() {
    return (
       <View
          style={{
            flex: 1,
            backgroundColor: "#ececec",
            flexDirection: "column",
            justifyContent: "center",
            alignItems: "center"
          }}
        >
          <View style={{ padding: 10, flexDirection: "row" }}>
            <TextInput
              style={{ flex: 0.8, height: 40, borderWidth: 1 }}
              onChangeText={text => this.setState({ text })}
              placeholder="Text 1"
              value={this.state.text}
            />
          </View>
          <View style={{ padding: 10, flexDirection: "row" }}>
            <TextInput
              style={{ flex: 0.8, height: 40, borderWidth: 1 }}
              onChangeText={text => this.setState({ text })}
              placeholder="Text 2"
              value={this.state.text}
            />
          </View>
          <View style={{ padding: 10, flexDirection: "row" }}>
            <Button
              onPress={onButtonPress}
              title="Press Me"
              accessibilityLabel="See an Information"
            />
          </View>
        </View>
    );
  }
}

0

Le moyen le plus simple consiste à appliquer une largeur à la vue.

width: '80%'
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.