具有React Native的iOS自适应布局

具有React Native的iOS自适应布局,ios,flexbox,react-native,ios-autolayout,Ios,Flexbox,React Native,Ios Autolayout,我已经和react native合作了几个星期了,现在我已经到了需要支持两种方向的地步。据称,flex box应该发挥其魔力,自动调整布局以适应新的屏幕大小。然而flex box并没有像我希望的那样处理这些变化,我并不是说它没有做应该做的事情,我只是说我对它不满意 更具体地说,我发现它基本上描述了我试图解决的问题(只有它们使用本机视图和自动布局)。我希望在设备旋转时实现布局更改(或者更一般地说,在大小更改时实现布局更改),类似于我链接的“迷你Instagram”示例 如何使用react nati

我已经和react native合作了几个星期了,现在我已经到了需要支持两种方向的地步。据称,flex box应该发挥其魔力,自动调整布局以适应新的屏幕大小。然而flex box并没有像我希望的那样处理这些变化,我并不是说它没有做应该做的事情,我只是说我对它不满意

更具体地说,我发现它基本上描述了我试图解决的问题(只有它们使用本机视图和自动布局)。我希望在设备旋转时实现布局更改(或者更一般地说,在大小更改时实现布局更改),类似于我链接的“迷你Instagram”示例


如何使用react native和flex box实现这一点?我应该为不同的屏幕大小使用不同的组件,还是有合适的方法来实现这一点?

我认为RN目前不会将任何旋转事件从本机发送到JS,但您将得到一个布局回调,因此您可以更新布局度量以响应此。e、 g:

getInitialState(): {
  return {isPortrait: true}; // You could use Dimensions to get this right initially?
},

render(): {
  // return a different layout depending on this.state.isPortrait
  return <View onLayout={this.onLayout} />
},

onLayout(e): {
  var isPortrait = e.nativeEvent.layout.height > e.nativeEvent.layout.width;
  if (isPortrait != this.state.isPortrait) {
    this.setState({isPortrait});
  }
}
getInitialState():{
return{isPortrait:true};//最初可以使用维度来实现这一点吗?
},
render():{
//根据此.state.isPortrait返回不同的布局
返回
},
仅限布置(e):{
var isPortrait=e.nativeEvent.layout.height>e.nativeEvent.layout.width;
if(isPortrait!=this.state.isPortrait){
this.setState({isPortrait});
}
}

注意:由于JS视图更新和布局都是异步进行的,因此很难与实际设备旋转更改的时间相匹配。

使用react native实现这一点需要做的工作不多。在这里,我试图演示与您要求的类似的视觉布局

我们只需要监听视图的onLayout事件,只要方向发生变化,就会调用该事件

通过比较Dimension.get('window')的高度和宽度,我们可以确定设备是处于纵向模式还是横向模式。下面是简单的代码

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));
    var imagel = this.props.list[0].src;
    var landscapeView =
                        <View style={{marginTop:20, flexDirection:'row'}}>
                          <Image source={require('./flower.jpg')} style={{height:this.state.layout.height-50, width:this.state.layout.width/2}}/>
                          <View>
                            <Text style={{backgroundColor:'gray', margin:5}}> header this is landscape view </Text>
                            <Text style={{backgroundColor:'gray',margin:5}}> footer this is portrait view  </Text>
                          </View>


                        </View>
    var portraitView = <View style={{marginTop:20}}>
                        <Text style={{backgroundColor:'gray', margin:5}}> header this is landscape view </Text>
                          <Image source={require('./flower.jpg')} style={{height:200, width:this.state.layout.width}}/>
                          <Text style={{backgroundColor:'gray',margin:5}}> footer this is portrait view  </Text>
                        </View>

    var cview =null;
    if (this.state.layout.height>this.state.layout.width) {
      cview = portraitView
    }else{
      cview = landscapeView;
    }
    return(
      <View style={{backgroundColor:'red', flex:1}}   onLayout={this._onLayout}>
      {cview}
      </View>
    );
  }
}
import React,{Component}来自'React';
进口{
样式表,
文本,
看法
形象,,
尺寸
}从“反应本机”;
var{height,width}=Dimensions.get('window');
导出默认类Com扩展组件{
构造函数(){
console.log('constructor');
超级();
此.state={
布局:{
高度:高度,,
宽度:宽度,
}
};
}
_onLayout=事件=>{
log('------------------------------------------------------------'+JSON.stringify(event.nativeEvent.layout));
这是我的国家({
布局:{
高度:event.nativeEvent.layout.height,
宽度:event.nativeEvent.layout.width,
}
});
}
render(){
log(JSON.stringify(this.props));
var imagel=this.props.list[0].src;
var景观视图=
标题这是横向视图
页脚这是纵向视图
变量视图=
标题这是横向视图
页脚这是纵向视图
var-cview=null;
if(this.state.layout.height>this.state.layout.width){
cview=纵向视图
}否则{
cview=景观视图;
}
返回(
{cview}
);
}
}
这里发生的事情是,我们正在收听事件onLayout,当方向发生变化时会触发该事件。然后我们有状态变量,它保持屏幕的实际高度和宽度,以反映方向的变化。我们使用此状态高度和宽度进行视图设计

这里发生了两件事

  • 在方向更改时调用onLayout
  • 更改状态值后,视图将再次渲染

  • 我知道如何识别大小更改(正如您建议的提供onLayout回调)。问题是什么是正确的处理方法?如果我需要像我所附的示例那样更改布局,渲染方法应该会有很大的变化,因此,也许我应该在同一个组件中使用两种渲染方法,或者我应该使用两种不同的组件?这实际上取决于视图树的复杂性。在您链接的示例中,使用纵向样式表可能比使用横向样式表简单,但在其他情况下,使用2种渲染方法可能是更好的方法。React本身并不关心这些方法之间的区别。谢谢。我对“唯一付款”活动很熟悉。你的建议基本上等同于有两个不同的组件——一个用于纵向,一个用于横向。是的,正确。这是因为布局在两个方向上完全不同。我如何将此值传递到我的
    style.js
    文件(另一个单独的文件),其中我需要不同方向的宽度和高度来进行样式设置?