Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Measuring a view without an onLayout returns an empty set of coordinates #19591

Closed
mmazzarolo opened this issue Jun 6, 2018 · 6 comments
Closed
Labels
Bug Resolution: Locked This issue was locked by the bot.

Comments

@mmazzarolo
Copy link

mmazzarolo commented Jun 6, 2018

Description

Measuring an Android View using ref.measureInWindow returns an empty set of coordinates if the onLayout prop of the View is not set.
The issue arises only when the View wraps some specific component like TouchableWithoutFeedback, TouchableNativeFeedback and TouchableOpacity.

Environment

Environment:

  • OS: macOS High Sierra 10.13.4
  • Node: 9.9.0
  • Yarn: 1.5.1
  • npm: 6.0.1
  • Watchman: 4.6.0
  • Xcode: Xcode 9.3.1 Build version 9E501
  • Android Studio: 2.3 AI-162.4069837

Packages: (wanted => installed)

  • react: 16.3.1 => 16.3.1
  • react-native: ~0.55.2 => 0.55.4

Steps to Reproduce

Create a new app using CRNA/Expo and change App.js like this:

/* @flow */
import * as React from "react";
import { StyleSheet, TouchableNativeFeedback, View } from "react-native";

class AndroidMeasureTester extends React.Component<{}> {
  boxRef: ?View = null;

  handleButtonPress = () => {
    if (this.boxRef) {
      this.boxRef.measureInWindow((x, y, width, height) => {
        console.debug("RED BOX LAYOUT:");
        console.debug("x", x);
        console.debug("y", y);
        console.debug("width", width);
        console.debug("height", height);
      });
    }
  };

  render() {
    return (
      <View style={styles.container}>
        <View ref={ref => (this.boxRef = ref)} onLayout={undefined}>
          <TouchableNativeFeedback onPress={this.handleButtonPress}>
            <View style={styles.box} />
          </TouchableNativeFeedback>
        </View>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    height: "100%",
    width: "100%",
    alignItems: "center",
    justifyContent: "center"
  },
  box: {
    width: 80,
    height: 80,
    backgroundColor: "red"
  }
});

export default AndroidMeasureTester;

I also created an Expo Snack.

Expected Behavior

Pressing the red square should always print the correct measures on consoles, even when its onLayout prop is undefined like in the example.
The correct printed layout should be something like:

06:25:31: RED BOX LAYOUT:
06:25:31: x 140
06:25:31: y 232
06:25:31: width 80
06:25:31: height 80

Actual Behavior

Pressing the red square prints the correct measures on consoles only when you set an onLayout (try setting onLayout={() => null} and you will see that it will works correctly).
If you don't se the onLayout, the result will be the following:

06:25:22: RED BOX LAYOUT:
06:25:22: x undefined
06:25:22: y undefined
06:25:22: width undefined
06:25:22: height undefined

Image recap

touch-measrure-issue

@mmazzarolo mmazzarolo changed the title Measuring a view without an onLayout returns an empty set of coordinates Measuring a view without an onLayout returns an undefined layout Jun 6, 2018
@mmazzarolo mmazzarolo changed the title Measuring a view without an onLayout returns an undefined layout Measuring a view without an onLayout return an empty set of coordinates Jun 6, 2018
@mmazzarolo mmazzarolo changed the title Measuring a view without an onLayout return an empty set of coordinates Measuring a view without an onLayout returns an empty set of coordinates Jun 6, 2018
@seanyu4296
Copy link

This is also happening in my end using react-native 0.56

@stale
Copy link

stale bot commented Nov 7, 2018

Hey there, it looks like there has been no activity on this issue recently. Has the issue been fixed, or does it still require the community's attention? This issue may be closed if no further activity occurs. You may also label this issue as "For Discussion" or "Good first issue" and I will leave it open. Thank you for your contributions.

@stale stale bot added the Stale There has been a lack of activity on this issue and it may be closed soon. label Nov 7, 2018
@mmazzarolo
Copy link
Author

It's still happening on [email protected]

@stale stale bot removed the Stale There has been a lack of activity on this issue and it may be closed soon. label Nov 7, 2018
@likern
Copy link

likern commented Nov 28, 2018

@mmazzarolo Its not exactly that case, but I have similar problem. Is it possible to set onLayout directly through ref, and not with property in JSX?

I want to get ref to external component and show popup menu tied up / stick to external component. And update position of popup whenever position of external component changes.

@gazedash
Copy link

gazedash commented Mar 12, 2019

Reproducible on [email protected] with or without onLayout!

@grabbou
Copy link
Contributor

grabbou commented Mar 19, 2019

This is expected behaviour (tho maybe it's possible to print a warning to make it more explicit?). On Android, Views that are only used for layout are removed from the hierarchy to save memory and speed. You need to set collapsable prop to false in order to make it stay in the layout hierarchy and be measurable.

Setting onLayout (even empty callback) automatically disables this operation too.

@grabbou grabbou closed this as completed Mar 19, 2019
@facebook facebook locked as resolved and limited conversation to collaborators Mar 19, 2020
@react-native-bot react-native-bot added the Resolution: Locked This issue was locked by the bot. label Mar 19, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Bug Resolution: Locked This issue was locked by the bot.
Projects
None yet
Development

No branches or pull requests

7 participants