我正在使用React-Native编写通用iPhone / iPad应用程序。但是当方向改变时,我正在努力正确地渲染我的视图。以下是js文件的源代码:
'use strict';
var React = require('react-native');
var {
Text,
View
} = React;
var CardView = require('./CardView');
var styles = React.StyleSheet.create({
container:{
flex:1,
backgroundColor: 'red'
}
});
class MySimpleApp extends React.Component {
render() {
return <View style={styles.container}/>;
}
}
React.AppRegistry.registerComponent('SimpleApp', () => MySimpleApp);
这是它在Portrait中呈现的方式(这是正确的):
然而,当设备旋转时。红色视图不会相应旋转。
答案 0 :(得分:13)
响应原生的方向变化非常简单。本机中的每个视图都有一个名为 onLayout 的侦听器,它会在方向更改时调用。我们只需要实现这一点。最好将维度存储在状态变量中并更新每个方向更改,以便在更改后重新呈现。另外,我们需要重新加载视图以响应方向更改。
import React, { Component } from "react";
import { StyleSheet, Text, View, Image, Dimensions } from "react-native";
var { height, width } = Dimensions.get("window");
export default class Com extends Component {
constructor() {
console.log("constructor");
super();
this.state = {
layout: {
height: height,
width: width
}
};
}
_onLayout = event => {
console.log(
"------------------------------------------------" +
JSON.stringify(event.nativeEvent.layout)
);
this.setState({
layout: {
height: event.nativeEvent.layout.height,
width: event.nativeEvent.layout.width
}
});
};
render() {
console.log(JSON.stringify(this.props));
return (
<View
style={{ backgroundColor: "red", flex: 1 }}
onLayout={this._onLayout}
>
<View
style={{
backgroundColor: "green",
height: this.state.layout.height - 10,
width: this.state.layout.width - 10,
margin: 5
}}
/>
</View>
);
}
}
答案 1 :(得分:12)
最简单的方法是:
import React, { Component } from 'react';
import { Dimensions, View, Text } from 'react-native';
export default class Home extends Component {
constructor(props) {
super(props);
this.state = {
width: Dimensions.get('window').width,
height: Dimensions.get('window').height,
}
this.onLayout = this.onLayout.bind(this);
}
onLayout(e) {
this.setState({
width: Dimensions.get('window').width,
height: Dimensions.get('window').height,
});
}
render() {
return(
<View
onLayout={this.onLayout}
style={{width: this.state.width}}
>
<Text>Layout width: {this.state.width}</Text>
</View>
);
}
}
答案 2 :(得分:6)
对于更新版本的React Native,方向更改不一定会触发onLayout,但Dimensions
提供更直接相关的事件:
class App extends Component {
constructor() {
super();
this.state = {
width: Dimensions.get('window').width,
height: Dimensions.get('window').height,
};
Dimensions.addEventListener("change", (e) => {
this.setState(e.window);
});
}
render() {
return (
<View
style={{
width: this.state.width,
height: this.state.height,
}}
>
</View>
);
}
}
请注意,此代码适用于应用的根组件。如果在应用程序中更深入地使用它,则需要包含相应的removeEventListener调用。
答案 3 :(得分:3)
您可以使用react-native-orientation来检测并执行方向更改的更改。
var Orientation = require('react-native-orientation');
还使用返回大小(宽度,高度)的Dimension类。
Dimensions.get('window')
使用这些方法玩方向
componentDidMount() {
Orientation.lockToPortrait(); //this will lock the view to Portrait
//Orientation.lockToLandscape(); //this will lock the view to Landscape
//Orientation.unlockAllOrientations(); //this will unlock the view to all Orientations
// self = this;
console.log('componentDidMount');
Orientation.addOrientationListener(this._orientationDidChange);
}
componentWillUnmount() {
console.log('componentWillUnmount');
Orientation.getOrientation((err,orientation)=> {
console.log("Current Device Orientation: ", orientation);
});
Orientation.removeOrientationListener(this._orientationDidChange);
}
_orientationDidChange(orientation) {
console.log('Orientation changed to '+orientation);
console.log(self);
if (orientation == 'LANDSCAPE') {
//do something with landscape layout
screenWidth=Dimensions.get('window').width;
console.log('screenWidth:'+screenWidth);
} else {
//do something with portrait layout
screenWidth=Dimensions.get('window').width;
console.log('screenWidth:'+screenWidth);
}
self.setState({
screenWidth:screenWidth
});
}
我也使用了它,但它的性能太低了。
希望有帮助...
答案 4 :(得分:0)
行。我找到了答案。需要在我们的viewcontroller中实现以下内容并调用刷新其中的ReactNative视图。
- (无效)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
答案 5 :(得分:0)
对于使用Exponent的任何人,您只需从exp.json
删除orientation
密钥。
答案 6 :(得分:0)
onLayout
或Dimensions.addEventListener
在React 16.3中都没有为我们工作。
这是一个flexbox hack,它可以根据方向变化来调整图像大小。 (我们还使用React的不错的但文献记录不多的ImageBackground组件在图像上方获取文本):
<View style={styles.container}>
<View style={styles.imageRowWithResizeHack}>
<ImageBackground
style={styles.imageContainer}
imageStyle={styles.thumbnailImg}
source={{ uri: thumbnailUrl }}
>
<View style={styles.imageText}>
<Text style={styles.partnerName}>{partnerName}</Text>
<Text style={styles.title}>{title.toUpperCase()}</Text>
</View>
</ImageBackground>
<View style={styles.imageHeight} />
</View>
</View>
const styles = StyleSheet.create({
container: {
position: 'relative',
flex: 1
},
imageRowWithResizeHack: {
flex: 1,
flexDirection: 'row'
},
imageContainer: {
flex: 1
},
imageHeight: {
height: 200
},
thumbnailImg: {
resizeMode: 'cover'
},
imageText: {
position: 'absolute',
top: 30,
left: TEXT_PADDING_LEFT
},
partnerName: {
fontWeight: '800',
fontSize: 20,
color: PARTNER_NAME_COLOR
},
title: {
color: COLOR_PRIMARY_TEXT,
fontSize: 90,
fontWeight: '700',
marginTop: 10,
marginBottom: 20
},
});
imageHeight
样式将设置View组件的高度(用户不可见),然后Flexbox将自动将同一行上的图像弯曲为相同高度。因此,您基本上是在间接设置图像的高度。 Flex会确保在方向发生变化时可以弯曲以填充整个容器。
答案 7 :(得分:0)
用户Rajan Twanabashu
给出的答案中的Appart,您还可以使用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 Component = ({ styles })=>(
<View style={styles.container}>
<Text>Some Text</Text>
</View>
);
// use `withStyles` Higher order Component.
Component = withStyles(styles)(Component);
export {
Component
};