如何在React Native中处理响应式布局

时间:2018-11-25 08:22:04

标签: react-native responsive-design

我正在使用react-native-dimension库来使我的UI响应如下:

const{width,height} = Dimensions.get('window');

以及在我的style.js文件中:

imageBackgroundLandscape:{
    width:height,
    height:width

},
imageBackgroundPortrait:{
    width:width,
    height:height
}

问题是,当我旋转屏幕时,width和height变量具有以前的值! 例如,在纵向模式下,我的变量是:

width : 800
height: 1280

当我旋转屏幕时,我的变量是:

width : 800 // previous value
height: 1280 // previous value

此外,我使用react-native-orientation来确定屏幕的模式。 我想知道在旋转设备时如何自动更改它们的值(宽度,高度),或者是否有其他用于此的库?

谢谢。

8 个答案:

答案 0 :(得分:2)

我通常使用以下代码处理height, width的混乱情况:

//Dimensions.js
import {Dimensions} from 'react-native';
const {height, width} = Dimensions.get('window');

const actualDimensions =  {
  height:  (height<width) ? width : height,
  width: (width>height) ? height : width
};

export default actualDimensions;

使用actualDimensions而不是从Dimensions要求高度和宽度,并且还可以尝试优美地管理方向。您还应该尝试使用this库。

Dimensions是在JS捆绑软件加载到应用程序之前加载的,因此建议为每个height, width动态获取render 您可以阅读此here

答案 1 :(得分:2)

尝试一下该库。真的很棒。它提供了一种声明式语法,可以轻松创建响应组件/布局

npmjs: https://stackoverflow.com/a/10388547/1709587

github https://www.npmjs.com/package/react-native-responsive-component

答案 2 :(得分:2)

您可以使用以下步骤使UI响应。

  1: use percentage whenever it's possible
  2: use the power of flexbox to make your UI grow and shrink
  3: use a library lik react-native-responsive-screen

答案 3 :(得分:1)

实际上,您完成的只是任务的一半。您从width获得了heightDimensions,这是正确的,但是react-native如何理解您的方向改变?

首先,您的代码应了解方向的变化,然后设置一个回调函数来更改应用程序的状态,以实现新的widthheight

很糟糕,我不知道react-native能否理解其内置功能的方向变化。因此,我使用this library来了解方向变化,然后使用setState重新呈现代码。

当然,我将widthheight放在组件的state内。

如果您想锁定方向更改,请使用this library

答案 4 :(得分:1)

我通常使用Flexbox来排列组件的布局。它可以帮助他们做出响应。也许您也可以尝试一下。

Layout with Flexbox

答案 5 :(得分:1)

首先

您面临的问题是因为方向改变后您忘记再次致电const{width,height} = Dimensions.get('window');。 为了在更改方向后获得widthheight的最新值,您必须再次调用Dimensions.get('window')函数并从其输出中获取宽度和高度。

第二

您可以只使用一个库(react-native-styleman),而不是使用多个库,这使您可以非常轻松地处理此类内容:

这是使用react-native-styleman时代码的样子。

import { withStyles } from 'react-native-styleman';
const styles = () => ({       
    container: {
        // your common styles here for container node.
        flex: 1,
        // lets write a media query to change background color automatically based on the device's orientation 
        '@media': [
          {
             orientation: 'landscape', // for landscape
             styles: {                 // apply following styles
                // these styles would be applied when the device is in landscape 
                // mode.
                 backgroundColor: 'green'
                 //.... more landscape related styles here...
             }
          },
          {
             orientation: 'portrait', // for portrait
             styles: {                // apply folllowing styles
                // these styles would be applied when the device is in portrait 
                // mode.
                 backgroundColor: 'red'
                 //.... more protrait related styles here...
             }
          }
        ]
    }
});

let MainComponent = ({ styles })=>(
    <View style={styles.container}>
        <Text> Hello World </Text>
    </View>
);

// now, lets wire up things together.
MainComponent = withStyles(styles)(MainComponent);

export {
  MainComponent
};

答案 6 :(得分:0)

react-native-lightweight-responsive可以将组件大小调整为每个设备上的优化大小。

答案 7 :(得分:0)

我正在使用react-native-responsive-screen。它也可以适应方向变化

用法

import {
  widthPercentageToDP as wp,
  heightPercentageToDP as hp,
  listenOrientationChange as lor,
  removeOrientationListener as rol
} from 'react-native-responsive-screen';

class Login extends Component {
  componentDidMount() {
    lor(this);
  }

  componentWillUnmount() {
    rol();
  }

  render() {
    const styles = StyleSheet.create({
      container: { flex: 1 },
      textWrapper: {
        height: hp('70%'),
        width: wp('80%')
      },
      myText: { fontSize: hp('5%') }
    });

    return (
      <View style={styles.container}>
        <View style={styles.textWrapper}>
          <Text style={styles.myText}>Login</Text>
        </View>
      </View>
    );
  }
}

export default Login;