React-Native : measure a View

react native measure()
react native createref
react native ref
react native element id
react-native measurelayout example
setnativeprops is not a function
react native get position of element in scrollview
react-native-on-layout

I'm trying to measure a view using a ref, but the width returned is 0 despite the fact that I see the view displayed on the screen (and it's far from being equal to 0).

I tried to follow this : https://github.com/facebook/react-native/issues/953 but it just doesn't work ... I just want to get the actual width of the View.

Here is my code :

var Time = React.createClass({
  getInitialState: function() {
    return({ progressMaxSize: 0 }); 
  },
  componentDidMount: function() {
    this.measureProgressBar();
  },
  measureProgressBar: function() {
    this.refs.progressBar.measure(this.setWidthProgressMaxSize);
  },
  setWidthProgressMaxSize: function(ox, oy, width, height, px, py) {
    this.setState({ progressMaxSize: width });
  },
  render: function() {
    return(
      <View style={listViewStyle.time} ref="progressBar">
        <View style={listViewStyle.progressBar} >
          <View style={[listViewStyle.progressMax, { width: this.state.progressMaxSize }]}/>
        </View>
      </View>
    );
  }
}); 

The styles associated :

time: {
    position: 'absolute',
    bottom: 5,
    left: 5,
    right: 5,
    backgroundColor: '#325436',
    flexDirection: 'row',
  },
  progressBar: {
    flex: 1,
    backgroundColor: '#0000AA',
  },
  progressMax: {
    position: 'absolute',
    top: 0,
    left: 0,
    backgroundColor: '#000',
    height: 30, 
  },

You want to measure the progress bar onLayout.

var Time = React.createClass({
  getInitialState: function() {
    return({ progressMaxSize: 0 }); 
  },
  measureProgressBar: function() {
    this.progressBar.measure(this.setWidthProgressMaxSize);
  },
  setWidthProgressMaxSize: function(ox, oy, width, height, px, py) {
    this.setState({ progressMaxSize: width });
  },
  render: function() {
    return(
      <View style={listViewStyle.time} ref={(c) => { this.progressBar = c; } onLayout={this.measureProgressBar}>
        <View style={listViewStyle.progressBar} >
          <View style={[listViewStyle.progressMax, { width: this.state.progressMaxSize }]}/>
        </View>
      </View>
    );
  }
});

Measuring a view without an onLayout returns an empty set , Description Measuring an Android View using ref.measureInWindow returns an empty react: 16.3.1 => 16.3.1; react-native: ~0.55.2 => 0.55.4  Views are designed to be used with StyleSheet for clarity and performance, although inline styles are also supported. Synthetic Touch Events. For View responder props (e.g., onResponderMove), the synthetic touch event passed to them are of the following form: nativeEvent. changedTouches - Array of all touch events that have changed since the last event.

To measure view size, no need to use ref at all. You can get it from nativeEvent passed by onLayout.

measureView(event: Object) {
   console.log(`*** event: ${JSON.stringify(event.nativeEvent)}`);
   // you'll get something like this here:
   // {"target":1105,"layout":{"y":0,"width":256,"x":32,"height":54.5}}
}

render() {
    return (
        <View onLayout={(event) => {this.measureView(event)}} />
    );
}

Direct Manipulation · React Native, `setNativeProps` is the React Native equivalent to setting properties directly on a Like measure() , but measures the view relative to an ancestor, specified as  Either way, the native View is given hard dimensions and can simply draw to the canvas provided. Simple. Not so simple when you want to draw text of dynamic length and font metrics. In this case the native View needs to provide an indication of required size to RN during the Flex measurement runs. Much like the measurement system in Android itself.

During the night some guys talked about a (hacky) solution but it solved my problem, found it here: https://github.com/facebook/react-native/issues/953

Basically the solution is to use setTimeout and everything just works magically:

componentDidMount: function() {
  setTimeout(this.measureProgressBar);
},

measureProgressBar: function() {
  this.refs.progressBar.measure((a, b, width, height, px, py) =>
    this.setState({ progressMaxSize: width })
  );
}

Measure and Get the Position of a React Native Element from , Additionally we'll see how to use the helper function measure on the component ref for easier measurement. Code. Become a Member to view code. You must be​  I want to measure the size of the content in my ScrollView. Therefore, I am using measure from NativeMethodsMixin: import NativeMethodsMixin from 'NativeMethodsMixin' I am not quite sure where

Measure and Get the Position of a React Native Element, In this lesson we'll explore how to measure the dimensions and get the position of a React Native element using onLayout and UIManager.measure. Additionally​  View component has a property called onLayout. You can use this property to get the position of that component. You can use this property to get the position of that component. onLayout

Measure Element in React Native with onLayout, In this video we'll learn how to measure the width of the full bar (so it works on variable screen Duration: 5:59 Posted: May 21, 2018 Where possible, we would like for React Native to do the right thing and help you to focus on your app instead of performance optimization, but there are areas where we're not quite there yet, and others where React Native (similar to writing native code directly) cannot possibly determine the best way to optimize for you and so manual intervention will be necessary.

Measuring a view without an onLayout returns an empty , js like this: /* @flow */ import * as React from "react"; import { StyleSheet, TouchableNativeFeedback, View } from "react-native";  A component's height and width determine its size on the screen. The simplest way to set the dimensions of a component is by adding a fixed width and height to style. All dimensions in React Native are unitless, and represent density-independent pixels. Setting dimensions this way is common for components that should always render at exactly

Comments
  • This is currently the best solution. I'm using React Native 0.50.4 and using a string ref is deprecated. Furthermore, the measure function of View will not return valid data unless onLayout is triggered at least once.
  • Actually somebody could tell me what ox, oy, width, height, px and py specifically mean?
  • onLayout doesn't call in some cases specially on Android.
  • You can also use requestAnimationFrame.
  • I get undefined is not an object (evaluating 'this.refs'). What's going on?
  • you need to bind measureProgressBar, this.measureProgressBar.bind(this)
  • It might be more efficient to only call measure in a callback passed to onLayout on your view.