Skip to content

fix(android): initial measuring tweaks - #784

Open
hejsztynx wants to merge 5 commits into
mainfrom
@ksienkiewicz/fix-android-initial-measuring
Open

fix(android): initial measuring tweaks#784
hejsztynx wants to merge 5 commits into
mainfrom
@ksienkiewicz/fix-android-initial-measuring

Conversation

@hejsztynx

@hejsztynx hejsztynx commented Aug 27, 2026

Copy link
Copy Markdown
Collaborator

Summary

When fontSize wasn't provided, the initial component height calculation was sometimes wrong if defaultValue was set.

During the calculation in initialMeasure, if fontSize wasn't provided via props, its value was 0, which caused the initial height estimation to be completely off. This edge case allowed to expose the real issue:

Normally, the layout should be refreshed even if the initialMeasure was off, but the calculated values were incorrectly cached, which didn't allow that. After run initialMeasure the shadow node received the estimated (wrong) height. After that the setValue runs, as we provided defaultValue, which requests a layout recalculation. The recalculation is done correctly, but the stateWrapper is not yet initialized (is null), which stops us from telling the shadow node to recalculate the layout, but still, the calculated sizes in MeasurementStore are cached anyway. That way MeasurementStore will not try to ask the shadow node for layout invalidation, as it incorrectly cached that the layout is fresh. This is now fixed and we only cache the sizes only if stateWrapper is present and we can safely assume that the information was delivered to the shadow node.

In initialMeasure, the fontSize now fallbacks to the default font size if <= 0. That's how it was already done in the initial EnrichedText measurements.

I've also tweaked two small things: in EnrichedTextInputShadowNode.cpp the forceHeightRecalculationCounter_ was never initialized before comparing its value, which would make it have random, garbage values. I've also adjusted the provided forceHeightRecalculationCounter to the stateWrapper, as its value was always pre-increment. I believe it's better to have them consistent.

Test Plan

I've provided a modified example app, so you can see the bug yourself - you can run

git checkout 212b2a3e

and then you can check out how it works after the fix

git checkout 4c478090

Screenshots / Videos

The race condition in action (stumbled across in a different app):

Screen.Recording.2026-08-27.at.12.12.20.mov

Compatibility

OS Implemented
iOS
Android
Web

Checklist

  • E2E tests are passing
  • Required E2E tests have been added (if applicable)

Copilot AI lite review requested due to automatic review settings August 27, 2026 10:38

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes an Android-only race in initial height estimation for EnrichedTextInputView when defaultValue is set and fontSize is missing/invalid, by preventing MeasurementStore from caching “fresh” sizes until the shadow node can actually be invalidated.

Changes:

  • Default fontSize used during initialMeasure now falls back to the view’s default when fontSize is null or <= 0.
  • MeasurementStore.store now invalidates the shadow node via a callback and only commits the new cached size when invalidation succeeds.
  • Initializes forceHeightRecalculationCounter_ in the shadow node and aligns the counter value sent via state updates.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

File Description
android/src/main/new_arch/react/renderer/components/ReactNativeEnrichedSpec/EnrichedTextInputShadowNode.h Initializes forceHeightRecalculationCounter_ to avoid undefined comparisons.
android/src/main/java/com/swmansion/enriched/textinput/MeasurementStore.kt Avoids caching new measured sizes unless shadow-node invalidation succeeds; improves fontSize fallback in initialMeasure.
android/src/main/java/com/swmansion/enriched/textinput/EnrichedTextInputViewLayoutManager.kt Passes an invalidation callback into MeasurementStore.store and updates the state counter post-increment.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@hejsztynx
hejsztynx requested a review from exploIF August 27, 2026 11:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants