Search code examples
androidreact-nativemeasure

How do I measure a custom native component in React Native on Android


I want to create a custom native component which renders a single line of text. The length of this text is dynamic and the typeface and size are configurable.

When I place my custom component in a standard <View /> the provided size constraints in View.onMeasure (native) are zero for height and this is MeasureSpec.EXACTLY. Returning any non-zero height in View.onMeasure does nothing.

class App extends React.Component<{}, undefined> {
  render() {
    return (
      <View style={{
          flex: 1,
        }}>
        <CustomComponent />
      </View>
    )
  }
}

How do I allow my custom native view to measure itself and provide this to React Native during measurement and layout?


Solution

  • After much time and effort I found the answer.

    You need to override ViewManager.getShadowNodeClass and provide a custom implementation of ReactShadowNode.

    Like so;

    public class CustomShadowNode extends LayoutShadowNode implements YogaMeasureFunction {
        public CustomShadowNode() {
            this.setMeasureFunction(this);
        }
    
        @Override
        public long measure(
          YogaNode node,
          float width, YogaMeasureMode widthMode,
          float height, YogaMeasureMode heightMode) {
          return YogaMeasureOutput.make(0, 0);
        }
    }
    

    I used LayoutShadowNode as it appears to handle the standard layout and styling props.

    I wrote more detail on the matter here.