Сделайте вид 80% ширины родителя в React Native

102

Я создаю форму в React Native и хочу сделать TextInput80% ширины экрана.

С HTML и обычным CSS это было бы просто:

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

За исключением того, что React Native не поддерживает displayсвойства, ширину в процентах или автоматические поля.

Так что же мне делать вместо этого? Там в некотором обсуждении этой проблемы в React отслеживания проблем туземца, но предлагаемые решения кажутся как противные писаки.

Марк Эмери
источник
1
react-nativeиспользуется flexдля размеров и положения элементов. Я не уверен, но может быть flex-basisэто то, что вам нужно: проверьте это и это
Аликс
1
И по этому вопросу что-то вроде flex: 0.8может сделать работу.
Аликс

Ответы:

90

Начиная с React Native 0.42 height:и width:принимайте проценты.

Используйте width: 80%в своих таблицах стилей, и это просто работает.

  • Снимок экрана

  • Живой пример
    дочерней ширины / высоты как пропорция родительской

  • Код

    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
источник
88

Это должно соответствовать вашим потребностям:

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
источник
17
просто <View style = {{width: '75% ', borderWidth: 1}}> </View>
user3044484 03
43

Если вы просто хотите вводить данные относительно ширины экрана, простым способом будет использовать 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 }} />

Я создал рабочий проект здесь . Код также ниже.

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 следует упомянуть пакет Dimensions на первой странице - это меня не удивляет ...
А.А. Карим
очень ценный ответ. Размеры на самом деле очень полезны. Примечание: «Хотя размеры доступны сразу, они могут измениться (например, из-за вращения устройства), поэтому любая логика или стили визуализации, зависящие от этих констант, должны пытаться вызывать эту функцию при каждой визуализации, а не кэшировать значение (например, используя встроенные стили вместо установки значения в таблице стилей) ".
Фил
Обратите внимание, что использование «Размеры» нарушает поворот экрана после публикации макетов, если вы поддерживаете альбомную ориентацию и не обрабатываете эти изменения макета вручную.
ratsimihah 04
25

В таблице стилей просто введите:

width: '80%';

вместо того:

width: 80%;

Продолжайте кодировать ........ :)

Кришна Радж Салим
источник
1
Можем ли мы использовать flexBasis: 80%вместо этого? @krishna
SureshCS50
@ SureshCS50: Еще не пробовал. Я надеюсь, ты сможешь. Подробнее здесь: stackoverflow.com/questions/43143258/…
Кришна Радж Салим
13

Вы также можете попробовать response-native-extended-stylesheet, который поддерживает процентное соотношение для приложений с одной ориентацией:

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

const styles = EStyleSheet.create({
  column: {
    width: '80%',
    height: '50%',
    marginLeft: '10%'
  }
});
виталец
источник
5

Техника, которую я использую для получения процентной ширины родительского элемента, заключается в добавлении дополнительного представления разделителя в сочетании с некоторым гибким боксом. Это не применимо ко всем сценариям, но может быть очень полезным.

Итак, начнем:

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

По сути, свойство flex - это ширина относительно «общей» гибкости всех элементов в гибком контейнере. Итак, если сумма всех пунктов равна 100, у вас есть процент. В этом примере я мог бы использовать значения гибкости 6 и 4 для того же результата, так что он еще более ГИБКИЙ.

Если вы хотите центрировать представление ширины в процентах: добавьте две прокладки половинной ширины. Итак, в примере это будет 2-6-2.

Конечно, добавление дополнительных представлений - не самая лучшая вещь в мире, но в реальном приложении я могу представить, что разделитель будет содержать другой контент.

dsdeur
источник
вы можете себе представить, что разделитель будет содержать разное содержание? Зачем? я могу придумать множество примеров, когда разделитель - это просто заполнитель html.
AlxVallejo
1

У меня есть обновленное решение (конец 2019 года), чтобы получить 80% ширины родительского элемента. В ответ с помощью крючков оно работает, даже если устройство вращается.

Вы можете использовать Dimensions.get('window').widthдля получения ширины устройства в этом примере, вы можете увидеть, как вы можете сделать это адаптивно

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

Вот так я и нашел решение. Просто и мило. Независимо от плотности экрана:

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

Самый простой способ добиться этого - применить ширину для просмотра.

width: '80%'
Кушал Десаи
источник