Ustaw widok 80% szerokości rodzica w React Native


101

Tworzę formularz w React Native i chciałbym, aby moje było TextInput80% szerokości ekranu.

W przypadku HTML i zwykłego CSS byłoby to proste:

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

Z wyjątkiem tego, że React Native nie obsługuje displaywłaściwości, szerokości procentowych ani automatycznych marginesów.

Więc co powinienem zrobić zamiast tego? Jest jakiś omówienie tego problemu w React emisyjnej tracker rodzimych, ale proponowane rozwiązania wydaje się nieprzyjemnych hacki.


1
react-nativeużywa flexdla rozmiarów i pozycji elementów. Nie jestem pewien, ale może to flex-basisjest to, czego potrzebujesz: Sprawdź to i to
alix

1
I w tej kwestii coś takiego flex: 0.8może załatwić sprawę .
alix

Odpowiedzi:


89

Od React Native 0.42 height:i width:zaakceptuj wartości procentowe.

Użyj width: 80%w swoich arkuszach stylów i po prostu działa.

  • Zrzut ekranu

  • Przykład na żywo
    Szerokość / wysokość dziecka jako proporcja rodzica

  • Kod

    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

To powinno pasować do Twoich potrzeb:

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

43

Jeśli chcesz po prostu wprowadzić dane w odniesieniu do szerokości ekranu, prostym sposobem byłoby użycie wymiarów:

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

Wcześniej skonfigurować projekt roboczy tutaj . Kod jest również poniżej.

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
React Native docs należy wymienić pakiet wymiary na pierwszej stronie - to, że nie mnie zadziwia ...
Aa Karim

bardzo cenna odpowiedź. Wymiary są w rzeczywistości bardzo przydatne. Uwaga: „Chociaż wymiary są dostępne od razu, mogą się zmienić (np. Z powodu obrotu urządzenia), więc każda logika renderowania lub style, które zależą od tych stałych, powinny próbować wywoływać tę funkcję przy każdym renderowaniu, zamiast buforować wartość (na przykład używając style wbudowane zamiast ustawiania wartości w arkuszu stylów) ”.
phil

Pamiętaj, że korzystanie z Wymiarów przerywa obrót ekranu po wyświetleniu układów, jeśli obsługujesz orientację poziomą i nie obsługujesz tych zmian układu ręcznie.
ratsimihah

25

W swoim arkuszu stylów po prostu wpisz:

width: '80%';

zamiast:

width: 80%;

Zachowaj kodowanie ........ :)


13

Możesz także wypróbować rozszerzony arkusz stylów, który obsługuje wartości procentowe dla aplikacji o pojedynczej orientacji:

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

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

5

Technika, której używam do uzyskania procentowej szerokości rodzica, polega na dodaniu dodatkowego widoku odstępnika w połączeniu z niektórymi flexboxami. Nie dotyczy to wszystkich scenariuszy, ale może być bardzo pomocne.

Więc zaczynamy:

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

Zasadniczo właściwość flex to szerokość w stosunku do „całkowitego” flexu wszystkich elementów w pojemniku flex. Więc jeśli suma wszystkich pozycji wynosi 100, masz procent. W przykładzie mógłbym użyć wartości flex 6 i 4 dla tego samego wyniku, więc jest jeszcze bardziej ELASTYCZNY.

Jeśli chcesz wyśrodkować widok szerokości w procentach: dodaj dwa odstępniki o połowie szerokości. W tym przykładzie byłoby to 2-6-2.

Oczywiście dodawanie dodatkowych widoków nie jest najmilszą rzeczą na świecie, ale w prawdziwej aplikacji mogę wyobrazić sobie, że spacer będzie zawierał inną zawartość.


możesz sobie wyobrazić, że spacer będzie zawierał inną zawartość? czemu? przychodzi mi do głowy wiele przykładów, w których odstępnik to po prostu wypełniacz html.
AlxVallejo

1

Mam zaktualizowane rozwiązanie (koniec 2019 r.), Aby uzyskać 80% szerokości rodzica responsywnego z hakami , działa, nawet jeśli urządzenie się obraca.

Możesz użyć, Dimensions.get('window').widthaby uzyskać szerokość urządzenia w tym przykładzie, aby zobaczyć, jak możesz to zrobić responsywnie

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

W ten sposób znalazłem rozwiązanie. Proste i słodkie. Niezależnie od gęstości ekranu:

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

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.