react-native: [Android] measure not returning values unless element has onLayout property

I have something similar to this:

handleSomething: function() {
  this._root.measure((ox, oy, width, height, px, py) => {
    console.log({ox, oy, width, height, px, py});
  });
},
render: function() {
  return (<View ref={component => this._root = component}>...</View>);
}

This code works flawlessly on iOS, but on android the measure callback will always be called with undefined arguments – unless I put an empty callback on the onLayout property.

About this issue

  • Original URL
  • State: closed
  • Created 9 years ago
  • Reactions: 21
  • Comments: 43 (21 by maintainers)

Commits related to this issue

Most upvoted comments

@oblador @marcshilling can you try collapsable: false prop on your view? Android may remove the view from hierarchy for optimization purpose.

I just ran into something similar.

https://facebook.github.io/react-native/docs/view.html#content

I’m also experiencing this. Along with onLayout, I’ve found that setting renderToHardwareTextureAndroid={true} on the view also makes measure return values.

@chirag04 collapsable: false helped for me, thanks.

I have same problem and can confirm that using onLayout or collapsable={false} helps

I have the same problem, but props arent undefined.

I have a listview with this rows:

  renderRow(rowData, sectionID, rowID) {
    return (
      <View
        style={{padding: 20, backgroundColor: rowData.color, marginHorizontal: 20, marginVertical: 10, alignItems: 'center'}}
        ref={(row) => this.rows[rowID] = row}
        collapsable={false}
        {...this.customPanResponder.panHandlers}
      >
        <Text>{rowData.text}</Text>
      </View>
    )
  }

With

    _.map(this.rows, row => {
          row.measure( (ox, oy, width, height, px, py) => console.log("ox: ", ox, " oy: ", oy, " height: ", height, " px: ", px, " py: ", py))
        })

On iOS measure logs:

ox:  20  oy:  10  height:  57  px:  20  py:  74
ox:  20  oy:  87  height:  57  px:  20  py:  151
ox:  20  oy:  164  height:  57  px:  20  py:  228

On Android measure logs:

ox:  0  oy:  0  height:  59  px:  20  py:  66
ox:  0  oy:  0  height:  59  px:  20  py:  145
ox:  0  oy:  0  height:  59  px:  20  py:  224

Why my oy on android is always 0?

i am using react native version 0.36 and got this issues on Android, but on iOS it work well here is my code ,

this.refs.field.measure((x, y, width, height, px, py) => { console.log('---------- height ',height) )}

height is undefined ?? pls help me, many thanks

I still see the issue of y coming through as 0 for Android, even after setting collapsable={false} on the View. Again, working fine in iOS.

@JAStanton I also tried setting collapsable={false} on the ScrollView up the tree, but that still did not help.

setting collapsable={false} on a View solved this problem for me. I’m on 0.39.2

I know this is closed but for anyone else who hit this when trying to get the x and y coordinates within a ScrollView, using measureLayout as @wschurman (thanks!) suggested worked for me.

For example:

import { findNodeHandle, ScrollView, View } from 'react-native'

...

this.VIEW_REF.measureLayout(
  findNodeHandle(this.SCROLLVIEW_REF),
  function(x, y) {
    console.log(x, y);
  }, 
  function(error) {
    console.log(error);
  }
);

...

render() {
  return (
    <ScrollView ref={ref => SCROLLVIEW_REF = ref}>
      <View ref={ref => VIEW_REF = ref}>
        ...
      </View>
    </ScrollView>
  );
}

@SteffeyDev I think you have to write a custom component, for iOS for example you can look for more information on how to scroll a UITextView to a selection: [textView scrollRangeToVisible:[textView.text rangeOfString:@"Lorem ipsum"]];

I just found that on iOS, measuring a Text component nested in another Text component results in all 0’s as well. Haven’t tested on Android yet. Also noted that onLayout on a nested Text component is never called, very strange.

Using measureLayout (relative to specific node) seemed to solve this for me.

Was this fixed in a more recent version? Using the unrelated properties onLayout or collapsable to force this functionality seems to me to be a hack rather than a fix. I know there are limited resources to fix things, but at least there could be something in the docs about it?

FYI, I’m using 0.26.3 and this was still an issue. I had to add an empty onLayout before measure would return integers instead of just undefined.

@ide that does not explain why it works on iOS 😕