在 React Native 中获取视图的大小

Posted

技术标签:

【中文标题】在 React Native 中获取视图的大小【英文标题】:Get size of a View in React Native 【发布时间】:2015-07-24 01:14:53 【问题描述】:

是否可以获取某个视图的大小(宽度和高度)?例如,我有一个显示进度的视图:

<View ref='progressBar' style=backgroundColor:'red',flex:this.state.progress /> 

我需要知道视图的实际宽度才能正确对齐其他视图。这可能吗?

【问题讨论】:

【参考方案1】:

从 React Native 0.4.2 开始,View 组件有一个onLayout prop。传入一个接受事件对象的函数。事件的nativeEvent 包含视图的布局。

<View onLayout=(event) => 
  var x, y, width, height = event.nativeEvent.layout;
 />

每当调整视图大小时,也会调用onLayout 处理程序。

主要需要注意的是,onLayout 处理程序是在组件安装后的一帧首先调用的,因此您可能希望隐藏 UI,直到计算完布局。

【讨论】:

这种方法的问题是当设备旋转/视图大小改变时,我没有再次调用 onLayout。 onLayout 在视图的框架改变时被调用。也许您的视图在旋转时不会改变其大小或位置。查看 UIExplorer 中的 onLayout 示例,其中 onLayout 在旋转时被调用。 假设我想根据尺寸不同地显示View。我不明白如何使用视图的onLayout 函数来更改视图的显示方式。这不会导致无限循环吗? @LaneRettig 是的,如果这确实是您想要做的,那么您应该以达到静态平衡的方式编写代码。但听起来您可能只想根据屏幕尺寸自定义视图,在这种情况下 onLayout 是不相关的。 @ide 在计算布局之前如何隐藏 UI?【参考方案2】:

这是唯一对我有用的东西:

import React,  Component  from 'react';
import 
  AppRegistry,
  StyleSheet,
  Text,
  View,
  Image
 from 'react-native';

export default class Comp extends Component 

  find_dimesions(layout)
    const x, y, width, height = layout;
    console.warn(x);
    console.warn(y);
    console.warn(width);
    console.warn(height);
  
  render() 
    return (
      <View onLayout=(event) =>  this.find_dimesions(event.nativeEvent.layout)  style=styles.container>
        <Text style=styles.welcome>
          Welcome to React Native!
        </Text>
        <Text style=styles.instructions>
          To get started, edit index.android.js
        </Text>
        <Text style=styles.instructions>
          Double tap R on your keyboard to reload,'\n'
          Shake or press menu button for dev menu
        </Text>
      </View>
    );
  


const styles = StyleSheet.create(
  container: 
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  ,
  welcome: 
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
  ,
  instructions: 
    textAlign: 'center',
    color: '#333333',
    marginBottom: 5,
  ,
);

AppRegistry.registerComponent('Comp', () => Comp);

【讨论】:

【参考方案3】:

基本上,如果您想设置大小并使其更改,然后将其设置为这样的布局状态:

import React,  Component  from 'react';
import  AppRegistry, StyleSheet, View  from 'react-native';

const styles = StyleSheet.create(
  container: 
    flex: 1,
    backgroundColor: 'yellow',
  ,
  View1: 
    flex: 2,
    margin: 10,
    backgroundColor: 'red',
    elevation: 1,
  ,
  View2: 
    position: 'absolute',
    backgroundColor: 'orange',
    zIndex: 3,
    elevation: 3,
  ,
  View3: 
    flex: 3,
    backgroundColor: 'green',
    elevation: 2,
  ,
  Text: 
    fontSize: 25,
    margin: 20,
    color: 'white',
  ,
);

class Example extends Component 

  constructor(props) 
    super(props);

    this.state = 
      view2LayoutProps: 
        left: 0,
        top: 0,
        width: 50,
        height: 50,
      
    ;
  

  onLayout(event) 
    const x, y, height, width = event.nativeEvent.layout;
    const newHeight = this.state.view2LayoutProps.height + 1;
    const newLayout = 
        height: newHeight ,
        width: width,
        left: x,
        top: y,
      ;

    this.setState( view2LayoutProps: newLayout );
  

  render() 
    return (
      <View style=styles.container>
        <View style=styles.View1>
          <Text>this.state.view2LayoutProps.height</Text>
        </View>
        <View onLayout=(event) => this.onLayout(event) 
              style=[styles.View2, this.state.view2LayoutProps] />
        <View style=styles.View3 />
      </View>
    );
  




AppRegistry.registerComponent(Example);

您可以创建更多修改方式的变体,方法是在另一个组件中使用它,该组件具有另一个视图作为包装器,并创建一个 onResponderRelease 回调,它可以将触摸事件位置传递给状态,然后可以传递将子组件作为属性,可以覆盖 onLayout 更新状态,通过放置[styles.View2, this.state.view2LayoutProps, this.props.touchEventTopLeft] 等等。

【讨论】:

【参考方案4】:

也许你可以使用measure:

measureProgressBar() 
    this.refs.welcome.measure(this.logProgressBarLayout);
,

logProgressBarLayout(ox, oy, width, height, px, py) 
  console.log("ox: " + ox);
  console.log("oy: " + oy);
  console.log("width: " + width);
  console.log("height: " + height);
  console.log("px: " + px);
  console.log("py: " + py);

【讨论】:

我这辈子都不知道如何正确使用NativeMethodsMixin。不管我做什么,measure 总是未定义的。有什么指点吗? 您不需要使用NativeMethodsMixin,该功能仅在某些元素上可用。例如TouchableWithFeedback 确实具有测量功能,但普通的Touchable 没有。尝试更改您正在使用的 View 的类型,获取 ref 并检查 measure 元素是否可用。我也偶然发现了这一点。【参考方案5】:

您可以通过onLayoutprops轻松获取View的大小。

import React from 'react'
import  View  from 'react-native'

export default function index() 
  const onLayout=(event)=> 
    const x, y, height, width = event.nativeEvent.layout;
    
  
  return (
    <View onLayout=onLayout>
      <OtherComponent />
    </View>
  )


每当调整视图大小时,也会调用onLayout 处理程序。

主要需要注意的是,onLayout 处理程序会在您的组件安装后的一帧中首先调用,因此您可能希望在计算完布局之前隐藏您的 UI。

【讨论】:

【参考方案6】:

您可以直接使用Dimensions 模块并计算您的视图大小。 实际上,Dimensions 提供了主窗口大小。

import  Dimensions  from 'Dimensions';

Dimensions.get('window').height;
Dimensions.get('window').width;

希望能帮到你!

更新:今天使用原生 StyleSheetFlex 在您的视图上排列有助于编写简洁的代码,并在广泛的情况下使用优雅的布局解决方案,而不是计算您的视图大小。 .

虽然构建一个自定义网格组件,它响应主窗口调整大小事件,但可以在简单的小部件组件中产生一个很好的解决方案

【讨论】:

这就是我要找的。谢谢! 呸,为什么没有更清楚地记录下来!?!我正在尝试使用 'width' 和 'height' 而不是 ('window').width 等。 @MarkAmery 带有窗口尺寸,您可以规划视图的外观 @BrunoGuerra 你能显示代码以按维度获取特定视图(而不是窗口)大小吗? 旋转设备时,许多设备上的尺寸不会更新。这是一个已知的issue,似乎从 react-native 0.32.0-rc.0 开始没有修复【参考方案7】:

对我来说,将尺寸设置为使用 % 对我有用 width:'100%'

【讨论】:

【参考方案8】:

这里是获取设备完整视图尺寸的代码。

var windowSize = Dimensions.get("window");

像这样使用它:

width=windowSize.width,heigth=windowSize.width/0.565

【讨论】:

这没关系,但它不能回答问题。

以上是关于在 React Native 中获取视图的大小的主要内容,如果未能解决你的问题,请参考以下文章

如何使用状态动态更改 React Native 转换?

如何在 React Native for Android 中调整字体大小以适应视图?

react-native - 适合包含视图的图像,而不是整个屏幕大小

如何在 react-native 中获取应用程序根目录

响应高度/宽度样式的 React Native 自定义 iOS 视图

在 react-native 中拖动形状并调整其大小