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

measureInWindow returns an incorrect Y coord on Android #19497

Closed
mmazzarolo opened this issue May 29, 2018 · 14 comments
Closed

measureInWindow returns an incorrect Y coord on Android #19497

mmazzarolo opened this issue May 29, 2018 · 14 comments
Labels
Bug Platform: Android Android applications. Stale There has been a lack of activity on this issue and it may be closed soon.

Comments

@mmazzarolo
Copy link

mmazzarolo commented May 29, 2018

Description

Measuring an Android View using NativeMethodsMixin.measureInWindow returns the incorrect Y coordinate.
It seems it always subtracts 24 (I guess it's the StatusBar height) from the Y coordinate.
It returns the correct value on iOS.

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, View, findNodeHandle } from "react-native";
// $FlowFixMe
import NativeMethodsMixin from "NativeMethodsMixin";

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

  handleBoxLayout = () => {
    if (this.boxRef) {
      NativeMethodsMixin.measureInWindow.call(
        findNodeHandle(this.boxRef),
        (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
          style={styles.box}
          ref={ref => (this.boxRef = ref)}
          onLayout={this.handleBoxLayout}
        />
      </View>
    );
  }
}

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

export default AndroidMeasureTester;

I also create an Expo Snack.

Expected Behavior

The measured Y coordinate should be 0 (it's printed on console):

x: 0
y: 0
width: 80
height: 80

Actual Behavior

The measured Y coordinate is -24 (it's printed on console):

x: 0
y: -24
width: 80
height: 80

Image recap

schermata 2018-05-29 alle 21 53 33

@react-native-bot react-native-bot added the Platform: Android Android applications. label May 29, 2018
@mmazzarolo
Copy link
Author

A Twitter comment highlighted an interesting point:

Not a RN user, but actually I think that's an android 5+ "issue". It's because android status bar management is changed. "window" element expands below the status bar on android 5+, so even a native app behave in this way (negative y). Maybe you need fitsSystemWindows (not sure)

Is the Y coord starting from -24 for keeping Android <5 backward compatibility?

Just to clarify: the main issue is that all the other measurement options (e.g.: XY coord obtained from a gesture) do not start from -24.

@anteloe
Copy link

anteloe commented May 30, 2018

Hi @mmazzarolo
To get zero-based coordinates, I used this:

import React from "react";
import { StyleSheet, Text, View } from "react-native";

export default class App extends React.Component {
  _onLayout = ({
    nativeEvent: {
      layout: { x, y, width, height }
    }
  }) => {
    console.log("x", x);
    console.log("y", y);
    console.log("width", width);
    console.log("height", height);
  };

  render() {
    return (
      <View style={styles.container}>
        <View style={styles.box} onLayout={this._onLayout} />
      </View>
    );
  }
}

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

see this: onLayout Documentation

let me know if I got you right or if I can help you further.

@mmazzarolo
Copy link
Author

mmazzarolo commented May 30, 2018

Hey @anteloe !
Yes, the nativeEvent param of onLayout callback works correctly (I think it uses measure, not measureInWindow under the hood) and I would suggest to always use it if possible instead of the measuring the View programmatically.

My point here was just reporting the measureInWindow inconsistency between platforms/versions for keeping track of it.

Thanks for the snippet anyway, it might be useful to someone looking for a valid alternative.

@stale
Copy link

stale bot commented Aug 28, 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 Aug 28, 2018
@mmazzarolo
Copy link
Author

mmazzarolo commented Aug 29, 2018

Has the issue been fixed

Nope

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

samu commented Oct 24, 2018

I have the same problem, but on iOS. In the simulator, it seems to be correct, but when running on a real device, the Y coordinate is wrong for example when the In-Call status bar is active.

In addition to that, i'm getting this warning when i use measureInWindow:

Warning: isMounted(...) is deprecated in plain JavaScript React classes. Instead, make sure to clean up subscriptions and pending requests in componentWillUnmount to prevent memory leaks

@lucasmotta
Copy link

lucasmotta commented Mar 5, 2019

I just encounter this problem, and after some investigation I notice that it happens only when the StatusBar is set to translucent. If I set this value to false it works just fine.

But that also leads me to another bug, which is when I use translucent, my views overlap the status bar:

screenshot_20190305-003501

@mmazzarolo
Copy link
Author

@lucasmotta is it a bug? That’s the behavior I would expect from the translucent StatusBar (and I don’t think is related to this issue) 🤔

@lucasmotta
Copy link

@mmazzarolo you are right, that's the expected behaviour. I had issue on Android only because my view was also wrapped on a SafeAreaView, which on iOS it pushes the content down a bit (height of the status bar), but on Android it does nothing - which is a shame the different behaviour. But thanks for pointing out, it's not related to this issue.

@KakarN
Copy link

KakarN commented Apr 19, 2019

I was using x of measureInWindow(), but in android, the status bar height was neglected as @mmazzarolo mentioned. Instead, now I am using pageX of measure(), which worked out fine for me.

@brunohkbx
Copy link
Contributor

+1
I couldn't find a way to properly get a correctly Y value

@quanvan05
Copy link

This issue still occur with Android device

@stale
Copy link

stale bot commented Oct 2, 2019

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 a "Discussion" or add it to the "Backlog" 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 Oct 2, 2019
@stale
Copy link

stale bot commented Oct 9, 2019

Closing this issue after a prolonged period of inactivity. If this issue is still present in the latest release, please feel free to create a new issue with up-to-date information.

@stale stale bot closed this as completed Oct 9, 2019
@facebook facebook locked as resolved and limited conversation to collaborators Oct 9, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Bug Platform: Android Android applications. Stale There has been a lack of activity on this issue and it may be closed soon.
Projects
None yet
Development

No branches or pull requests

9 participants