diff --git a/android/src/main/java/com/reactnativenavigation/views/stack/topbar/titlebar/TitleBarReactButtonView.java b/android/src/main/java/com/reactnativenavigation/views/stack/topbar/titlebar/TitleBarReactButtonView.java index f9b6e9bfae..8db15b6a9c 100644 --- a/android/src/main/java/com/reactnativenavigation/views/stack/topbar/titlebar/TitleBarReactButtonView.java +++ b/android/src/main/java/com/reactnativenavigation/views/stack/topbar/titlebar/TitleBarReactButtonView.java @@ -50,10 +50,12 @@ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { // before the content has laid out that width is collapsed (~1px), Fabric lays the content into // it and the button never recovers (#8320/#8326 did this and regressed under the New Arch). // - // Height: EXACTLY the available bar height. Giving the surface a filled height (rather than a - // content-hugging AT_MOST height) lets content that centers itself (e.g. a flex container with - // justifyContent: 'center') sit vertically centered in the bar, matching the legacy layout. - // It does not cause the width collapse — only a forced width does. + // Height: bounded (AT_MOST) so the surface sizes to its content height. The view is then + // centered vertically by the toolbar's action-view layout and the CENTER_VERTICAL gravity set + // in onViewAdded(). Forcing EXACTLY the full bar height (as #8328 did) made the surface fill + // the bar, so content-hugging buttons that don't self-center (plain text like "Publish", a + // fixed-size avatar image) were pinned to the top. AT_MOST height does NOT cause the width + // collapse — only a forced EXACTLY *width* does. int widthSpec = component.width.hasValue() ? createExactSpec(component.width) : makeMeasureSpec(resolveAvailableWidth(widthMeasureSpec), AT_MOST); @@ -66,7 +68,7 @@ private int createHeightSpec(int measureSpec, Number dimension) { return createExactSpec(dimension); } int availableSize = MeasureSpec.getSize(measureSpec); - return makeMeasureSpec(availableSize > 0 ? availableSize : Math.max(resolveActionBarSize(), 1), EXACTLY); + return makeMeasureSpec(availableSize > 0 ? availableSize : Math.max(resolveActionBarSize(), 1), AT_MOST); } private int resolveAvailableWidth(int measureSpec) { diff --git a/android/src/test/java/com/reactnativenavigation/views/TitleBarReactButtonViewTest.java b/android/src/test/java/com/reactnativenavigation/views/TitleBarReactButtonViewTest.java index 407270476c..6e0f886271 100644 --- a/android/src/test/java/com/reactnativenavigation/views/TitleBarReactButtonViewTest.java +++ b/android/src/test/java/com/reactnativenavigation/views/TitleBarReactButtonViewTest.java @@ -34,12 +34,14 @@ public class TitleBarReactButtonViewTest extends BaseTest { // Without explicit dimensions the button measures the hosted React surface ONCE: // - width AT_MOST → the surface sizes itself to its content (max-of-children under Fabric). - // - height EXACTLY the available bar height → the surface gets a filled box so content that - // centers itself (flex justifyContent: 'center') stays vertically centered in the bar. + // - height AT_MOST → the surface sizes to its content height; the view is then centered + // vertically in the bar by the toolbar's action-view layout + the CENTER_VERTICAL gravity from + // onViewAdded(). A forced EXACTLY full-bar height would pin content-hugging buttons (plain + // text, a fixed-size avatar) to the top. // It deliberately does not push a forced EXACTLY *width*; under the New Architecture that re-pushes // a (initially collapsed) width to the async Fabric layout and the button never recovers. @Test - public void missingDimensionsSizeWidthToContentAndFillHeight() { + public void missingDimensionsSizeToContent() { Activity activity = newActivity(); TitleBarReactButtonView uut = createView(activity, new ComponentOptions()); RecordingContentView child = new RecordingContentView(activity); @@ -48,11 +50,11 @@ public void missingDimensionsSizeWidthToContentAndFillHeight() { uut.measure(makeMeasureSpec(PARENT_WIDTH, AT_MOST), makeMeasureSpec(PARENT_HEIGHT, AT_MOST)); assertThat(uut.getMeasuredWidth()).isEqualTo(CHILD_WIDTH); - assertThat(uut.getMeasuredHeight()).isEqualTo(PARENT_HEIGHT); + assertThat(uut.getMeasuredHeight()).isEqualTo(CHILD_HEIGHT); assertThat(child.widthMeasureSpecs.size()).isEqualTo(1); assertThat(getMode(child.widthMeasureSpecs.get(0))).isEqualTo(AT_MOST); assertThat(getSize(child.widthMeasureSpecs.get(0))).isEqualTo(PARENT_WIDTH); - assertThat(getMode(child.heightMeasureSpecs.get(0))).isEqualTo(EXACTLY); + assertThat(getMode(child.heightMeasureSpecs.get(0))).isEqualTo(AT_MOST); assertThat(getSize(child.heightMeasureSpecs.get(0))).isEqualTo(PARENT_HEIGHT); } @@ -78,7 +80,7 @@ public void explicitDimensionsMeasureExactly() { } @Test - public void zeroParentSpecsFallBackToScreenWidthAndActionBarHeight() { + public void zeroParentSpecsFallBackToScreenWidthAndBoundedActionBarHeight() { Activity activity = newActivity(); TitleBarReactButtonView uut = createView(activity, new ComponentOptions()); RecordingContentView child = new RecordingContentView(activity); @@ -90,12 +92,12 @@ public void zeroParentSpecsFallBackToScreenWidthAndActionBarHeight() { assertThat(getMode(child.widthMeasureSpecs.get(0))).isEqualTo(AT_MOST); assertThat(getSize(child.widthMeasureSpecs.get(0))) .isEqualTo(Math.max(activity.getResources().getDisplayMetrics().widthPixels, 1)); - assertThat(getMode(child.heightMeasureSpecs.get(0))).isEqualTo(EXACTLY); + assertThat(getMode(child.heightMeasureSpecs.get(0))).isEqualTo(AT_MOST); assertThat(getSize(child.heightMeasureSpecs.get(0))).isEqualTo(Math.max(resolveActionBarSize(activity), 1)); } @Test - public void rtlMissingDimensionsUseBoundedWidthAndFilledHeight() { + public void rtlMissingDimensionsUseBoundedWidthAndHeight() { Activity activity = newActivity(); TitleBarReactButtonView uut = createView(activity, new ComponentOptions()); RecordingContentView child = new RecordingContentView(activity); @@ -107,7 +109,7 @@ public void rtlMissingDimensionsUseBoundedWidthAndFilledHeight() { assertThat(child.widthMeasureSpecs.size()).isEqualTo(1); assertThat(getMode(child.widthMeasureSpecs.get(0))).isEqualTo(AT_MOST); assertThat(getSize(child.widthMeasureSpecs.get(0))).isEqualTo(PARENT_WIDTH); - assertThat(getMode(child.heightMeasureSpecs.get(0))).isEqualTo(EXACTLY); + assertThat(getMode(child.heightMeasureSpecs.get(0))).isEqualTo(AT_MOST); assertThat(getSize(child.heightMeasureSpecs.get(0))).isEqualTo(PARENT_HEIGHT); }