在React Native中获取视图的大小

Mat*_*hew 123 ios react-native

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

<View ref='progressBar' style={{backgroundColor:'red',flex:this.state.progress}} /> 
Run Code Online (Sandbox Code Playgroud)

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

ide*_*ide 264

从React Native 0.4.2开始,View组件有一个onLayoutprop.传递一个接受事件对象的函数.该事件nativeEvent包含视图的布局.

<View onLayout={(event) => {
  var {x, y, width, height} = event.nativeEvent.layout;
}} />
Run Code Online (Sandbox Code Playgroud)

onLayout每当视图被调整处理器也将被调用.

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

  • @ide如何在计算布局之前隐藏UI? (5认同)
  • 这种方法的问题是当设备旋转/视图大小更改时,我不会再次调用 onLayout。 (4认同)
  • 当视图的帧发生更改时,将调用onLayout.也许您的视图不会改变其旋转的大小或位置.查看UIExplorer中的onLayout示例,其中onLayout在旋转时调用. (3认同)
  • 假设我想根据尺寸不同地显示"视图".我不明白如何使用View的`onLayout`函数来改变我显示View的方式.这不会导致无限循环吗? (2认同)
  • @LaneRettig是的,如果这是你想要做的事情,那么你应该以达到静态均衡的方式编写代码.但听起来你可能只想根据屏幕尺寸自定义你的视图,在这种情况下`onLayout`是无关的. (2认同)

Bru*_*rra 28

您可以直接使用该Dimensions模块并计算您的视图大小.实际上,Dimensions给你主窗口大小.

import { Dimensions } from 'Dimensions';

Dimensions.get('window').height;
Dimensions.get('window').width;
Run Code Online (Sandbox Code Playgroud)

希望能帮到你!

  • 您给出的示例提供了*window*的尺寸,而不是给定视图的尺寸; 这有什么关系? (220认同)
  • 旋转设备时,许多设备上的尺寸不会更新.这是一个已知的[问题](https://github.com/yamill/react-native-orientation/issues/3),并且似乎没有像react-native 0.32.0-rc.0那样修复 (4认同)
  • Gah,为什么这个记录得更清楚了!?!我正在尝试'宽度'和'高度'而不是('窗口').宽度等. (3认同)
  • @BrunoGuerra你可以通过Dimensions显示获得特定视图(非窗口)大小的代码吗? (2认同)

Abh*_*mar 19

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

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);
Run Code Online (Sandbox Code Playgroud)


Yin*_*eng 10

也许你可以使用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);
}
Run Code Online (Sandbox Code Playgroud)

  • 您不需要使用`NativeMethodsMixin`该函数仅适用于某些元素.例如`TouchableWithFeedback`确实有测量功能,但常规的`Touchable`没有.尝试更改您正在使用的"View"类型,获取ref并检查measure元素是否可用.我偶然发现了这一点. (2认同)

jus*_*tek 9

基本上,如果您想设置大小并进行更改,请将其设置为布局状态,如下所示:

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);
Run Code Online (Sandbox Code Playgroud)

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


Muh*_*man 7

您可以轻松获得Viewby onLayout props的大小。

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>
  )
}

Run Code Online (Sandbox Code Playgroud)

onLayout处理器也将被调用每当视图大小。

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