在 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】:
您可以通过onLayout
props轻松获取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;
希望能帮到你!
更新:今天使用原生 StyleSheet
和 Flex 在您的视图上排列有助于编写简洁的代码,并在广泛的情况下使用优雅的布局解决方案,而不是计算您的视图大小。 .
虽然构建一个自定义网格组件,它响应主窗口调整大小事件,但可以在简单的小部件组件中产生一个很好的解决方案
【讨论】:
这就是我要找的。谢谢! 呸,为什么没有更清楚地记录下来!?!我正在尝试使用 '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 for Android 中调整字体大小以适应视图?
react-native - 适合包含视图的图像,而不是整个屏幕大小