From 500ab02f2fe28333dfc691033c6e0d56bb34b797 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Du=C5=BCy?= <91994767+alduzy@users.noreply.github.com> Date: Mon, 28 Oct 2024 13:14:46 +0100 Subject: [PATCH] fix(Android): center headerTitleAlign below Android API 29 (#2439) ## Description This PR intents to fix `headerTitleAlign: 'center'` breaking layout on android API <= 29. I found changes added in https://github.com/software-mansion/react-native-screens/pull/2332, which fixed a related toolbar problem on android API <= 29, affect the correct layout of the centered title. The `EXACTLY` [MeasureSpec](https://developer.android.com/reference/android/view/View.MeasureSpec) causes the title not to obtain as much space as it needs. Fortunately changing the spec to `AT_MOST` in the custom `layoutCallback` fixes the issue without introducing regression. I also included a check for the current `softInputMode` to abandon the action if it is not set to `adjustPan`. Fixes #2435 ## Changes - updated `Test2332.tsx` repro - changed measureSpec used in `layoutCallback` - added `softInputMode` check ## Screenshots / GIFs | Before https://github.com/software-mansion/react-native-screens/pull/2332 | Before | After | | --- | --- | --- | | ![Screenshot_20241024_114026](https://github.com/user-attachments/assets/58cd349c-dd26-47ae-b05e-a391f6573672) | ![Screenshot_20241024_113943](https://github.com/user-attachments/assets/902fc554-ebfd-4bd3-81a0-c0fc70bd038f) | ![Screenshot_20241024_113853](https://github.com/user-attachments/assets/b60c0e2f-e3a2-4921-bde9-55750bdb617c) | ## Test code and steps to reproduce - use `Test2332.tsx` repro ## Checklist - [x] Included code example that can be used to test this change - [x] Ensured that CI passes --- .../com/swmansion/rnscreens/CustomToolbar.kt | 16 +++++++++++++--- apps/src/tests/Test2332.tsx | 2 +- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/android/src/main/java/com/swmansion/rnscreens/CustomToolbar.kt b/android/src/main/java/com/swmansion/rnscreens/CustomToolbar.kt index 1cff34143c..d581cd6ed7 100644 --- a/android/src/main/java/com/swmansion/rnscreens/CustomToolbar.kt +++ b/android/src/main/java/com/swmansion/rnscreens/CustomToolbar.kt @@ -3,9 +3,11 @@ package com.swmansion.rnscreens import android.annotation.SuppressLint import android.content.Context import android.os.Build +import android.view.WindowManager import androidx.appcompat.widget.Toolbar import com.facebook.react.modules.core.ChoreographerCompat import com.facebook.react.modules.core.ReactChoreographer +import com.facebook.react.uimanager.ThemedReactContext // This class is used to store config closer to search bar @SuppressLint("ViewConstructor") // Only we construct this view, it is never inflated. @@ -18,9 +20,11 @@ open class CustomToolbar( object : ChoreographerCompat.FrameCallback() { override fun doFrame(frameTimeNanos: Long) { isLayoutEnqueued = false + // The following measure specs are selected to work only with Android APIs <= 29. + // See https://github.com/software-mansion/react-native-screens/pull/2439 measure( - MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), - MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY), + MeasureSpec.makeMeasureSpec(width, MeasureSpec.AT_MOST), + MeasureSpec.makeMeasureSpec(height, MeasureSpec.AT_MOST), ) layout(left, top, right, bottom) } @@ -28,7 +32,13 @@ open class CustomToolbar( override fun requestLayout() { super.requestLayout() - if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.Q) { + val softInputMode = + (context as ThemedReactContext) + .currentActivity + ?.window + ?.attributes + ?.softInputMode + if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.Q && softInputMode == WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN) { // Below Android API 29, layout is not being requested when subviews are being added to the layout, // leading to having their subviews in position 0,0 of the toolbar (as Android don't calculate // the position of each subview, even if Yoga has correctly set their width and height). diff --git a/apps/src/tests/Test2332.tsx b/apps/src/tests/Test2332.tsx index 9728439194..7642ac0267 100644 --- a/apps/src/tests/Test2332.tsx +++ b/apps/src/tests/Test2332.tsx @@ -76,7 +76,7 @@ const DetailsScreen = () => { function App() { return ( - +