在React Native中使视图的父级宽度为80%


98

我正在React Native中创建一个表单,并希望使TextInput屏幕宽度达到80%。

使用HTML和普通CSS,这很简单:

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

除了React Native不支持display属性,百分比宽度或自动边距。

那我该怎么办呢?有这个问题的一些讨论中作出反应原住民的问题跟踪器,但提出的解决方案似乎是讨厌的黑客。


1
react-native用途flex为元素的大小和位置。我不知道,但可能flex-basis是你所需要的:检查
阿利克斯

1
根据这个问题,类似的事情flex: 0.8可能会起作用。
alix 2015年

Answers:


83

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

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

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

41

如果您只是想相对于屏幕宽度进行输入,则一种简单的方法是使用尺寸:

// 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包-不会令我惊讶...
AA Karim

非常有价值的答案。尺寸实际上非常有用。注意:“尽管尺寸立即可用,但它们可能会发生变化(例如由于设备旋转),因此任何依赖于这些常量的渲染逻辑或样式都应尝试在每个渲染上调用此函数,而不是缓存值(例如,使用内嵌样式,而不是在StyleSheet中设置值)。”
菲尔

请注意,如果您支持横向并且不手动处理这些布局更改,则使用“尺寸标注”会中断屏幕旋转后的布局。
ratsimihah


13

您还可以尝试支持单一方向应用程序百分比的react-native-extended-stylesheet

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

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

5

我使用的具有父级百分比宽度的技术是结合一些flexbox添加一个额外的间隔视图。这并非适用于所有情况,但可能会很有帮助。

所以我们开始:

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属性是相对于flex容器中所有项目的“全部” flex的宽度。因此,如果所有项目的总和为100,则您有一个百分比。在示例中,我可以为相同的结果使用flex值6和4,因此它甚至更灵活。

如果要使百分比宽度视图居中:添加两个宽度为一半的垫片。因此,在示例中为2-6-2。

当然,添加额外的视图并不是世界上最好的事情,但是在现实世界中的应用程序中,我可以对间隔符进行成像以包含不同的内容。


您可以想象间隔符将包含不同的内容吗?为什么?我可以想到很多例子,其中间隔符只是填充html。
AlxVallejo

1

我有一个更新的解决方案(2019年末),可以使用Hooks响应地获得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>
    );
  }
}

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.