我正在使用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中呈现的方式(这是正确的):
但是,当设备旋转时。红色视图不会相应旋转。
在本地反应中响应方向变化非常简单。本机中的每个视图都有一个名为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>
);
}
}
最简单的方法是:
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>
);
}
}
对于更新版本的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调用。
您可以使用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
});
}
我也用过这个,但它的性能太低了。
希望有帮助......
好。我找到了答案。需要在我们的viewcontroller中实现以下内容并在其中调用刷新我们的ReactNative视图。
- (无效)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
对于任何使用Exponent的人,您只需要从orientation
中删除exp.json
密钥。
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将确保它弯曲以在方向更改时填充整个容器。