首页 文章

React Native:获取元素的位置

提问于
浏览
44

我正在设计一个带有flexbox的 Image 组件,它位于屏幕的中心,效果非常好 . 现在我希望第二个 Image 组件直接显示在第一个组件的顶部 . 第二张图像使用绝对定位 . 目前我只是猜测像素,以便适合,但当然这不准确,而且可维护性太大 .

我几乎在寻找与jQuery的 .offset() 相当的React Native . 有没有这样的事情,如果没有_1680813这是实现这一目标的最佳途径?

5 回答

  • 0

    React Native提供了一个.measure(...)方法,该方法接受回调并使用组件的偏移量和宽度/高度调用它:

    myComponent.measure( (fx, fy, width, height, px, py) => {
    
        console.log('Component width is: ' + width)
        console.log('Component height is: ' + height)
        console.log('X offset to frame: ' + fx)
        console.log('Y offset to frame: ' + fy)
        console.log('X offset to page: ' + px)
        console.log('Y offset to page: ' + py)
    })
    

    示例......

    下面计算自定义组件呈现后的布局:

    class MyComponent extends React.Component {
        render() {
            return <View ref={view => { this.myComponent = view; }} />
        }
        componentDidMount() {
            // Print component dimensions to console
            this.myComponent.measure( (fx, fy, width, height, px, py) => {
                console.log('Component width is: ' + width)
                console.log('Component height is: ' + height)
                console.log('X offset to frame: ' + fx)
                console.log('Y offset to frame: ' + fy)
                console.log('X offset to page: ' + px)
                console.log('Y offset to page: ' + py)
            })        
        }
    }
    

    Bug说明

    • 请注意,有时组件在调用 componentDidMount() 之前未完成渲染 . 如果你从 measure(...) 得到零,那么将它包装在 setTimeout 应该可以解决问题,即:
    setTimeout( myComponent.measure(...), 0 )
    
  • 58

    我需要在ListView中找到一个元素的位置,并使用这个类似于 .offset 的片段:

    const UIManager = require('NativeModules').UIManager;
    const handle = React.findNodeHandle(this.refs.myElement);
    UIManager.measureLayoutRelativeToParent(
      handle, 
      (e) => {console.error(e)}, 
      (x, y, w, h) => {
        console.log('offset', x, y, w, h);
      });
    

    这假设我的组件上有 ref='myElement' .

  • 13

    您可以使用onLayout在组件可用的最早时刻获取组件的宽度,高度和相对父级位置:

    <View
      onLayout={event => {
        const layout = event.nativeEvent.layout;
        console.log('height:', layout.height);
        console.log('width:', layout.width);
        console.log('x:', layout.x);
        console.log('y:', layout.y);
      }}
    >
    

    using .measure() as shown in the accepted answer相比,这样做的好处是,您永远不必随意使用 setTimeout 推迟 .measure() 调用,以确保测量结果可用,但缺点是它不是't give you offsets relative to the entire page, only ones relative to the element'的父级 .

  • 1

    我有一个类似的问题,并通过结合上面的答案解决它

    class FeedPost extends React.Component {
      constructor(props) {
        ...
        this.handleLayoutChange = this.handleLayoutChange.bind(this);
      }
    
    
    handleLayoutChange() {
        this.feedPost.measure( (fx, fy, width, height, px, py) => {
          console.log('Component width is: ' + width)
          console.log('Component height is: ' + height)
          console.log('X offset to page: ' + px)
          console.log('Y offset to page: ' + py)
        })
      }
    
      render {
        return(
          <View onLayout={(event) => {this.handleLayoutChange(event) }} 
          ref={view => { this.feedPost = view; }} >
    ...
    

    现在我可以在日志中看到feedPost元素的位置:

    08-24 11:15:36.838  3727 27838 I ReactNativeJS: Component width is: 156
    08-24 11:15:36.838  3727 27838 I ReactNativeJS: Component height is: 206
    08-24 11:15:36.838  3727 27838 I ReactNativeJS: X offset to page: 188
    08-24 11:15:36.838  3727 27838 I ReactNativeJS: Y offset to page: 870
    
  • 16

    在使用refs计算时,最新版本的React Native似乎已经改变了 .

    以这种方式声明引用 .

    <View
        ref={(image) => {
        this._image = image
      }}>
    

    并以这种方式找到 Value .

    _measure = () => {
        this._image._component.measure((width, height, px, py, fx, fy) => {
          const location = {
            fx: fx,
            fy: fy,
            px: px,
            py: py,
            width: width,
            height: height
          }
          console.log(location)
        })
      }
    

相关问题