Hacer ver el 80% del ancho del padre en React Native

98

Estoy creando un formulario en React Native y me gustaría hacer que mi TextInputs 80% del ancho de la pantalla.

Con HTML y CSS normal, esto sería sencillo:

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

Excepto que React Native no admite la displaypropiedad, los anchos de porcentaje ni los márgenes automáticos.

Entonces, ¿qué debo hacer en su lugar? Hay una cierta discusión de este problema en React seguimiento de incidencias de nativos, pero las soluciones propuestas parecen como cortes desagradables.

Mark Amery
fuente
1
react-nativeusos flexpara los tamaños y posiciones de los elementos. No estoy seguro, pero es posible que flex-basissea ​​lo que necesita: verifique esto y esto
alix
1
Y de acuerdo con este tema, algo como flex: 0.8puede hacer el trabajo.
alix

Respuestas:

84

A partir de React Native 0.42 height:y width:acepta porcentajes.

Úselo width: 80%en sus hojas de estilo y simplemente funciona.

  • Captura de pantalla

  • Ejemplo en vivo
    Ancho / Alto del niño como proporción del padre

  • Código

    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>
    );
GollyJer
fuente
88

Eso debería ajustarse a sus necesidades:

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>
        );
    }
});
neciu
fuente
17
solo <View style = {{width: '75% ', borderWidth: 1}}> </View>
user3044484
41

Si simplemente está buscando hacer la entrada relativa al ancho de la pantalla, una forma fácil sería usar Dimensiones:

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

He creado un proyecto de trabajo aquí . El código también está debajo.

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);
Nader Dabit
fuente
6
Los documentos de React Native deberían mencionar el paquete Dimensions en la página principal, eso no me sorprende ...
AA Karim
respuesta muy valiosa. Las dimensiones son realmente muy útiles. Nota: "Aunque las dimensiones están disponibles de inmediato, pueden cambiar (por ejemplo, debido a la rotación del dispositivo), por lo que cualquier lógica o estilo de representación que dependa de estas constantes debe intentar llamar a esta función en cada representación, en lugar de almacenar en caché el valor (por ejemplo, usando estilos en línea en lugar de establecer un valor en una hoja de estilo) ".
phil
Tenga en cuenta que el uso de Dimensiones interrumpe sus diseños después de la rotación de la pantalla si admite el paisaje y no maneja esos cambios de diseño manualmente.
ratsimihah
22

En su StyleSheet, simplemente ponga:

width: '80%';

en vez de:

width: 80%;

Sigue codificando ........ :)

Krishna Raj Salim
fuente
13

También puede probar react-native-extended-stylesheet que admite porcentaje para aplicaciones de orientación única:

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

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

La técnica que utilizo para tener un porcentaje de ancho del padre es agregar una vista de espaciador adicional en combinación con algo de flexbox. Esto no se aplicará a todos los escenarios, pero puede resultar muy útil.

Así que, aquí vamos:

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

Básicamente, la propiedad flex es el ancho relativo a la flexión "total" de todos los elementos del contenedor flexible. Entonces, si todos los elementos suman 100, tiene un porcentaje. En el ejemplo, podría haber usado valores flexibles 6 y 4 para el mismo resultado, por lo que es aún más FLEXible.

Si desea centrar la vista de ancho porcentual: agregue dos espaciadores con la mitad del ancho. Entonces, en el ejemplo sería 2-6-2.

Por supuesto, agregar las vistas adicionales no es lo mejor del mundo, pero en una aplicación del mundo real puedo imaginar que el espaciador contendrá contenido diferente.

dsdeur
fuente
¿Puedes imaginar que el espaciador tendrá contenido diferente? ¿por qué? Puedo pensar en muchos ejemplos en los que un espaciador es simplemente un relleno HTML.
AlxVallejo
1

Tengo una solución actualizada (finales de 2019), para obtener un 80% de ancho de padre Responsively con Hooks , funciona incluso si el dispositivo gira.

Puede usar Dimensions.get('window').widthpara obtener el ancho del dispositivo en este ejemplo, puede ver cómo puede hacerlo de manera receptiva

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',
     },
});
Shayan Moghadam
fuente
0

Esta es la forma en que obtuve la solución. Simple y dulce. Independiente de la densidad de la pantalla:

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>
    );
  }
}
sagar suri
fuente
0

La forma más sencilla de lograrlo es aplicando ancho a la vista.

width: '80%'
Kushal Desai
fuente