Faça uma visualização de 80% da largura do pai no React Native

97

Estou criando um formulário no React Native e gostaria de fazer TextInput80% da largura da tela.

Com HTML e CSS comum, isso seria simples:

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

Exceto que o React Native não oferece suporte à displaypropriedade, larguras de porcentagem ou margens automáticas.

Então, o que devo fazer? Há alguma discussão sobre esse problema no rastreador de problemas do React Native, mas as soluções propostas parecem hacks desagradáveis.

Mark Amery
fonte
1
react-nativeusa flexpara tamanhos e posições dos elementos. Não tenho certeza, mas pode ser o flex-basisque você precisa: Verifique isto e isto
alix
1
E de acordo com esta questão, algo como flex: 0.8pode fazer o trabalho.
alix

Respostas:

80

A partir de React Native 0,42 height:e width:aceitar porcentagens.

Use width: 80%em suas folhas de estilo e ele simplesmente funciona.

  • Captura de tela

  • Largura / altura da criança de exemplo ao vivo
    como proporção do pai

  • 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
fonte
88

Isso deve atender às suas necessidades:

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
fonte
17
apenas <View style = {{width: '75% ', borderWidth: 1}}> </View>
user3044484
41

Se você está simplesmente procurando fazer a entrada em relação à largura da tela, uma maneira fácil seria usar Dimensões:

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

Eu montei um projeto de trabalho aqui . O código também está abaixo.

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
fonte
6
Os documentos do React Native devem mencionar o pacote Dimensions na página inicial - isso não me surpreende ...
AA Karim
uma resposta muito valiosa. Dimensões é realmente muito útil. Nota: "Embora as dimensões estejam disponíveis imediatamente, elas podem mudar (por exemplo, devido à rotação do dispositivo), então qualquer lógica de renderização ou estilos que dependam dessas constantes devem tentar chamar esta função em cada renderização, em vez de armazenar o valor em cache (por exemplo, usando estilos embutidos em vez de definir um valor em uma StyleSheet). "
phil
Observe que o uso de Dimensões quebra seus layouts após a rotação da tela se você suportar paisagem e não lidar com essas alterações de layout manualmente.
ratsimihah
22

Em seu StyleSheet, basta colocar:

width: '80%';

ao invés de:

width: 80%;

Continue codificando ........ :)

Krishna Raj Salim
fonte
13

Você também pode tentar a folha de estilo react-native-extended-style que suporta porcentagem para aplicativos de orientação única:

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

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

A técnica que uso para obter a largura percentual do pai é adicionar uma visualização de espaçador extra em combinação com algum flexbox. Isso não se aplica a todos os cenários, mas pode ser muito útil.

Aqui vamos nos:

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

Basicamente, a propriedade flex é a largura relativa ao flex "total" de todos os itens no flex container. Portanto, se todos os itens somam 100, você tem uma porcentagem. No exemplo, eu poderia ter usado os valores flex 6 e 4 para o mesmo resultado, então é ainda mais FLEXível.

Se você deseja centralizar a visualização da largura percentual: adicione dois espaçadores com metade da largura. Portanto, no exemplo seria 2-6-2.

É claro que adicionar visualizações extras não é a coisa mais legal do mundo, mas em um aplicativo do mundo real, posso imaginar que o espaçador terá conteúdo diferente.

dsdeur
fonte
você pode imaginar que o espaçador terá conteúdo diferente? porque? Posso pensar em muitos exemplos em que um espaçador é apenas um preenchimento html.
AlxVallejo
1

Eu tenho uma solução atualizada (final de 2019), para obter 80% de largura do pai responsivamente com ganchos funciona mesmo se o dispositivo girar.

Você pode usar Dimensions.get('window').widthpara obter a largura do dispositivo neste exemplo, você pode ver como pode fazer isso responsivamente

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

Foi assim que consegui a solução. Simples e doce. Independente da densidade da tela:

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

A maneira mais fácil de conseguir é aplicando largura para ver.

width: '80%'
Kushal Desai
fonte