react-native-navigation 8.8.1 → 8.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/android/build.gradle +1 -0
- package/android/src/main/java/com/reactnativenavigation/NavigationActivity.java +48 -1
- package/android/src/main/java/com/reactnativenavigation/react/modal/ModalHostLayout.kt +2 -2
- package/android/src/main/java/com/reactnativenavigation/utils/ReactTypefaceUtils.java +1 -2
- package/android/src/main/java/com/reactnativenavigation/utils/SystemUiUtils.kt +219 -54
- package/android/src/main/java/com/reactnativenavigation/viewcontrollers/bottomtabs/BottomTabsController.java +3 -2
- package/android/src/main/java/com/reactnativenavigation/viewcontrollers/bottomtabs/BottomTabsPresenter.kt +26 -6
- package/android/src/main/java/com/reactnativenavigation/viewcontrollers/component/ComponentViewController.java +6 -3
- package/android/src/main/java/com/reactnativenavigation/viewcontrollers/viewcontroller/LayoutDirectionApplier.kt +1 -2
- package/android/src/main/java/com/reactnativenavigation/viewcontrollers/viewcontroller/Presenter.java +3 -5
- package/android/src/main/java/com/reactnativenavigation/viewcontrollers/viewcontroller/ViewController.java +2 -6
- package/android/src/main/java/com/reactnativenavigation/views/bottomtabs/BottomTabsContainer.kt +5 -0
- package/android/src/test/java/com/reactnativenavigation/viewcontrollers/stack/TopBarControllerTest.kt +0 -1
- package/ios/BottomTabsAppearancePresenter.mm +17 -5
- package/ios/RNNBottomTabsController.mm +1 -4
- package/ios/RNNCommandsHandler.mm +29 -23
- package/ios/RNNOverlayManager.mm +2 -0
- package/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/statusbar/StatusBarPresenter.kt +212 -0
- package/lib/module/events/EventsRegistry.test.js.map +1 -1
- package/package.json +2 -2
- package/src/events/EventsRegistry.test.tsx +3 -3
package/android/build.gradle
CHANGED
|
@@ -130,6 +130,7 @@ dependencies {
|
|
|
130
130
|
implementation "androidx.constraintlayout:constraintlayout:2.0.4"
|
|
131
131
|
|
|
132
132
|
implementation 'androidx.appcompat:appcompat:1.7.0'
|
|
133
|
+
implementation 'androidx.activity:activity:1.9.0'
|
|
133
134
|
implementation 'androidx.annotation:annotation:1.2.0'
|
|
134
135
|
implementation 'com.google.android.material:material:1.2.0-alpha03'
|
|
135
136
|
|
|
@@ -7,6 +7,7 @@ import android.os.Build;
|
|
|
7
7
|
import android.os.Bundle;
|
|
8
8
|
import android.view.KeyEvent;
|
|
9
9
|
import android.view.View;
|
|
10
|
+
import android.view.ViewGroup;
|
|
10
11
|
|
|
11
12
|
import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler;
|
|
12
13
|
import com.facebook.react.modules.core.PermissionAwareActivity;
|
|
@@ -17,10 +18,12 @@ import com.reactnativenavigation.viewcontrollers.viewcontroller.RootPresenter;
|
|
|
17
18
|
import com.reactnativenavigation.react.JsDevReloadHandler;
|
|
18
19
|
import com.reactnativenavigation.react.ReactGateway;
|
|
19
20
|
import com.reactnativenavigation.react.CommandListenerAdapter;
|
|
21
|
+
import com.reactnativenavigation.utils.SystemUiUtils;
|
|
20
22
|
import com.reactnativenavigation.viewcontrollers.child.ChildControllersRegistry;
|
|
21
23
|
import com.reactnativenavigation.viewcontrollers.modal.ModalStack;
|
|
22
24
|
import com.reactnativenavigation.viewcontrollers.navigator.Navigator;
|
|
23
25
|
|
|
26
|
+
import androidx.activity.EdgeToEdge;
|
|
24
27
|
import androidx.activity.OnBackPressedCallback;
|
|
25
28
|
import androidx.annotation.NonNull;
|
|
26
29
|
import androidx.annotation.Nullable;
|
|
@@ -36,6 +39,7 @@ public class NavigationActivity extends AppCompatActivity implements DefaultHard
|
|
|
36
39
|
|
|
37
40
|
@Override
|
|
38
41
|
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
|
42
|
+
enableEdgeToEdge();
|
|
39
43
|
super.onCreate(savedInstanceState);
|
|
40
44
|
if (isFinishing()) {
|
|
41
45
|
return;
|
|
@@ -63,7 +67,19 @@ public class NavigationActivity extends AppCompatActivity implements DefaultHard
|
|
|
63
67
|
@Override
|
|
64
68
|
public void onPostCreate(@Nullable Bundle savedInstanceState) {
|
|
65
69
|
super.onPostCreate(savedInstanceState);
|
|
66
|
-
|
|
70
|
+
ViewGroup contentLayout = findViewById(android.R.id.content);
|
|
71
|
+
navigator.setContentLayout(contentLayout);
|
|
72
|
+
SystemUiUtils.setupSystemBarBackgrounds(this, contentLayout);
|
|
73
|
+
applyThemeStatusBarColor();
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
private void applyThemeStatusBarColor() {
|
|
77
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM
|
|
78
|
+
&& SystemUiUtils.needsManualStatusBarBackground()) {
|
|
79
|
+
//noinspection deprecation
|
|
80
|
+
getWindow().setStatusBarColor(android.graphics.Color.TRANSPARENT);
|
|
81
|
+
SystemUiUtils.setStatusBarColor(getWindow(), android.graphics.Color.TRANSPARENT);
|
|
82
|
+
}
|
|
67
83
|
}
|
|
68
84
|
|
|
69
85
|
@Override
|
|
@@ -88,6 +104,7 @@ public class NavigationActivity extends AppCompatActivity implements DefaultHard
|
|
|
88
104
|
@Override
|
|
89
105
|
protected void onDestroy() {
|
|
90
106
|
super.onDestroy();
|
|
107
|
+
SystemUiUtils.tearDown();
|
|
91
108
|
if (navigator != null) {
|
|
92
109
|
navigator.destroy();
|
|
93
110
|
}
|
|
@@ -146,6 +163,36 @@ public class NavigationActivity extends AppCompatActivity implements DefaultHard
|
|
|
146
163
|
navigator.destroyViews();
|
|
147
164
|
}
|
|
148
165
|
|
|
166
|
+
/**
|
|
167
|
+
* Controls when edge-to-edge is enabled. Override to customize the decision logic.
|
|
168
|
+
* Call {@link #activateEdgeToEdge()} from your override to enable edge-to-edge.
|
|
169
|
+
* <p>
|
|
170
|
+
* The default implementation enables edge-to-edge only if the app theme sets
|
|
171
|
+
* {@code windowOptOutEdgeToEdgeEnforcement} to {@code false} (API 35+).
|
|
172
|
+
* Called at the start of onCreate, before super.onCreate.
|
|
173
|
+
*/
|
|
174
|
+
protected void enableEdgeToEdge() {
|
|
175
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM) {
|
|
176
|
+
android.content.res.TypedArray a = getTheme().obtainStyledAttributes(
|
|
177
|
+
new int[]{android.R.attr.windowOptOutEdgeToEdgeEnforcement});
|
|
178
|
+
boolean optOut = a.getBoolean(0, true);
|
|
179
|
+
a.recycle();
|
|
180
|
+
if (!optOut) {
|
|
181
|
+
activateEdgeToEdge();
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Enables edge-to-edge display and notifies the navigation framework.
|
|
188
|
+
* Call this from {@link #enableEdgeToEdge()} overrides instead of
|
|
189
|
+
* calling {@code EdgeToEdge.enable()} directly.
|
|
190
|
+
*/
|
|
191
|
+
protected void activateEdgeToEdge() {
|
|
192
|
+
EdgeToEdge.enable(this);
|
|
193
|
+
SystemUiUtils.activateEdgeToEdge();
|
|
194
|
+
}
|
|
195
|
+
|
|
149
196
|
protected void addDefaultSplashLayout() {
|
|
150
197
|
View view = new View(this);
|
|
151
198
|
setContentView(view);
|
|
@@ -34,8 +34,8 @@ open class ModalHostLayout(reactContext: ThemedReactContext) : ViewGroup(reactCo
|
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
@TargetApi(23)
|
|
37
|
-
override fun dispatchProvideStructure(structure: ViewStructure) {
|
|
38
|
-
mHostView.dispatchProvideStructure(
|
|
37
|
+
override fun dispatchProvideStructure(structure: ViewStructure?) {
|
|
38
|
+
structure?.let { mHostView.dispatchProvideStructure(it) }
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {}
|
|
@@ -18,9 +18,8 @@ import android.graphics.Typeface;
|
|
|
18
18
|
import android.text.TextUtils;
|
|
19
19
|
import androidx.annotation.Nullable;
|
|
20
20
|
import com.facebook.react.bridge.ReadableArray;
|
|
21
|
-
import com.facebook.react.common.ReactConstants;
|
|
22
21
|
import com.facebook.react.views.text.ReactFontManager;
|
|
23
|
-
import com.facebook.react.
|
|
22
|
+
import com.facebook.react.common.ReactConstants;
|
|
24
23
|
import java.util.ArrayList;
|
|
25
24
|
import java.util.List;
|
|
26
25
|
|
|
@@ -3,10 +3,14 @@ package com.reactnativenavigation.utils
|
|
|
3
3
|
import android.app.Activity
|
|
4
4
|
import android.graphics.Color
|
|
5
5
|
import android.graphics.Rect
|
|
6
|
+
import android.graphics.drawable.ColorDrawable
|
|
7
|
+
import android.view.Gravity
|
|
6
8
|
import android.view.View
|
|
9
|
+
import android.view.ViewGroup
|
|
7
10
|
import android.view.Window
|
|
11
|
+
import android.widget.FrameLayout
|
|
8
12
|
import androidx.annotation.ColorInt
|
|
9
|
-
import androidx.core.view.
|
|
13
|
+
import androidx.core.view.ViewCompat
|
|
10
14
|
import androidx.core.view.WindowInsetsCompat
|
|
11
15
|
import androidx.core.view.WindowInsetsControllerCompat
|
|
12
16
|
import kotlin.math.abs
|
|
@@ -16,8 +20,18 @@ object SystemUiUtils {
|
|
|
16
20
|
private const val STATUS_BAR_HEIGHT_M = 24
|
|
17
21
|
internal const val STATUS_BAR_HEIGHT_TRANSLUCENCY = 0.65f
|
|
18
22
|
private var statusBarHeight = -1
|
|
19
|
-
|
|
23
|
+
|
|
24
|
+
const val DEFAULT_NAV_BAR_COLOR = Color.BLACK
|
|
25
|
+
private const val THREE_BUTTON_NAV_BAR_OPACITY = 0.8f
|
|
26
|
+
|
|
27
|
+
private var statusBarBackgroundView: View? = null
|
|
28
|
+
private var statusBarBackgroundActivity: java.lang.ref.WeakReference<Activity>? = null
|
|
29
|
+
private var navBarBackgroundView: View? = null
|
|
30
|
+
@JvmStatic
|
|
31
|
+
var isEdgeToEdgeActive = false
|
|
20
32
|
private set
|
|
33
|
+
private var isThreeButtonNav = false
|
|
34
|
+
private var lastExplicitNavBarColor: Int? = null
|
|
21
35
|
|
|
22
36
|
@JvmStatic
|
|
23
37
|
fun getStatusBarHeight(activity: Activity?): Int {
|
|
@@ -45,98 +59,222 @@ object SystemUiUtils {
|
|
|
45
59
|
statusBarHeight = height
|
|
46
60
|
}
|
|
47
61
|
|
|
48
|
-
|
|
49
62
|
@JvmStatic
|
|
50
63
|
fun getStatusBarHeightDp(activity: Activity?): Int {
|
|
51
|
-
return UiUtils.pxToDp(activity, getStatusBarHeight(activity).toFloat())
|
|
52
|
-
.toInt()
|
|
64
|
+
return UiUtils.pxToDp(activity, getStatusBarHeight(activity).toFloat()).toInt()
|
|
53
65
|
}
|
|
54
66
|
|
|
67
|
+
// region Setup
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Initializes view-based system bar backgrounds for edge-to-edge.
|
|
71
|
+
* Call from Activity.onPostCreate after the navigator content layout is set.
|
|
72
|
+
*
|
|
73
|
+
* Status bar: reuses the system's android:id/statusBarBackground DecorView child
|
|
74
|
+
* when available. On API 35+ with EdgeToEdge, this view may not exist, so a
|
|
75
|
+
* manual view is created in the content layout, sized by status bar insets.
|
|
76
|
+
* Navigation bar: creates a view in [contentLayout] sized by WindowInsets,
|
|
77
|
+
* since the system's navigationBarBackground is not available with EdgeToEdge.
|
|
78
|
+
*/
|
|
55
79
|
@JvmStatic
|
|
56
|
-
fun
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
80
|
+
fun setupSystemBarBackgrounds(activity: Activity, contentLayout: ViewGroup) {
|
|
81
|
+
setupStatusBarBackground(activity)
|
|
82
|
+
setupNavigationBarBackground(contentLayout)
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
private fun setupStatusBarBackground(activity: Activity) {
|
|
86
|
+
if (statusBarBackgroundView != null) return
|
|
87
|
+
val sbView = activity.window.decorView.findViewById<View>(android.R.id.statusBarBackground)
|
|
88
|
+
if (sbView != null) {
|
|
89
|
+
statusBarBackgroundView = sbView
|
|
90
|
+
} else {
|
|
91
|
+
statusBarBackgroundActivity = java.lang.ref.WeakReference(activity)
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
private fun ensureStatusBarBackgroundView(): View? {
|
|
96
|
+
statusBarBackgroundView?.let { return it }
|
|
97
|
+
val activity = statusBarBackgroundActivity?.get() ?: return null
|
|
98
|
+
val contentLayout = activity.findViewById<ViewGroup>(android.R.id.content) ?: return null
|
|
99
|
+
val view = View(activity)
|
|
100
|
+
val params = FrameLayout.LayoutParams(
|
|
101
|
+
FrameLayout.LayoutParams.MATCH_PARENT, 0, Gravity.TOP
|
|
102
|
+
)
|
|
103
|
+
contentLayout.addView(view, params)
|
|
104
|
+
statusBarBackgroundView = view
|
|
105
|
+
statusBarBackgroundActivity = null
|
|
106
|
+
|
|
107
|
+
ViewCompat.setOnApplyWindowInsetsListener(view) { v, insets ->
|
|
108
|
+
val sbHeight = insets.getInsets(WindowInsetsCompat.Type.statusBars()).top
|
|
109
|
+
val lp = v.layoutParams
|
|
110
|
+
if (lp.height != sbHeight) {
|
|
111
|
+
lp.height = sbHeight
|
|
112
|
+
v.layoutParams = lp
|
|
62
113
|
}
|
|
114
|
+
insets
|
|
63
115
|
}
|
|
116
|
+
view.requestApplyInsets()
|
|
117
|
+
return view
|
|
64
118
|
}
|
|
65
119
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
WindowInsetsControllerCompat(window, view).show(WindowInsetsCompat.Type.navigationBars())
|
|
120
|
+
private fun setupNavigationBarBackground(contentLayout: ViewGroup) {
|
|
121
|
+
if (navBarBackgroundView != null) return
|
|
122
|
+
val view = View(contentLayout.context).apply {
|
|
123
|
+
setBackgroundColor(Color.BLACK)
|
|
71
124
|
}
|
|
125
|
+
val params = FrameLayout.LayoutParams(
|
|
126
|
+
FrameLayout.LayoutParams.MATCH_PARENT, 0, Gravity.BOTTOM
|
|
127
|
+
)
|
|
128
|
+
contentLayout.addView(view, params)
|
|
129
|
+
navBarBackgroundView = view
|
|
130
|
+
|
|
131
|
+
ViewCompat.setOnApplyWindowInsetsListener(view) { v, insets ->
|
|
132
|
+
val navBarHeight = insets.getInsets(WindowInsetsCompat.Type.navigationBars()).bottom
|
|
133
|
+
val tappableHeight = insets.getInsets(WindowInsetsCompat.Type.tappableElement()).bottom
|
|
134
|
+
val wasThreeButton = isThreeButtonNav
|
|
135
|
+
isThreeButtonNav = tappableHeight > 0
|
|
136
|
+
if (isThreeButtonNav != wasThreeButton) {
|
|
137
|
+
val color = lastExplicitNavBarColor ?: getDefaultNavBarColor()
|
|
138
|
+
v.setBackgroundColor(color)
|
|
139
|
+
}
|
|
140
|
+
val lp = v.layoutParams
|
|
141
|
+
if (lp.height != navBarHeight) {
|
|
142
|
+
lp.height = navBarHeight
|
|
143
|
+
v.layoutParams = lp
|
|
144
|
+
}
|
|
145
|
+
insets
|
|
146
|
+
}
|
|
147
|
+
view.requestApplyInsets()
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Returns the default navigation bar color, applying 80% opacity for 3-button navigation.
|
|
152
|
+
* Gesture navigation gets a fully opaque color since the bar is minimal.
|
|
153
|
+
*/
|
|
154
|
+
@JvmStatic
|
|
155
|
+
fun getDefaultNavBarColor(): Int {
|
|
156
|
+
if (!isThreeButtonNav) return DEFAULT_NAV_BAR_COLOR
|
|
157
|
+
val alpha = (THREE_BUTTON_NAV_BAR_OPACITY * 255).toInt()
|
|
158
|
+
return Color.argb(alpha, Color.red(DEFAULT_NAV_BAR_COLOR), Color.green(DEFAULT_NAV_BAR_COLOR), Color.blue(DEFAULT_NAV_BAR_COLOR))
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Returns true when the system statusBarBackground view was not found during setup,
|
|
163
|
+
* meaning a manual view will be lazily created on the first setStatusBarColor call.
|
|
164
|
+
* Use this to decide whether to apply a theme-based initial status bar color.
|
|
165
|
+
*/
|
|
166
|
+
@JvmStatic
|
|
167
|
+
fun needsManualStatusBarBackground(): Boolean = statusBarBackgroundActivity != null
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Marks edge-to-edge as active. Call after EdgeToEdge.enable() in the activity.
|
|
171
|
+
* This flag controls whether navigation bar insets are forwarded to SafeAreaView
|
|
172
|
+
* and whether the view-based nav bar background is used for color changes.
|
|
173
|
+
*/
|
|
174
|
+
@JvmStatic
|
|
175
|
+
fun activateEdgeToEdge() {
|
|
176
|
+
isEdgeToEdgeActive = true
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Clears references to system bar background views.
|
|
181
|
+
* Call from Activity.onDestroy to avoid leaking views across activity recreation.
|
|
182
|
+
*/
|
|
183
|
+
@JvmStatic
|
|
184
|
+
fun tearDown() {
|
|
185
|
+
statusBarBackgroundView = null
|
|
186
|
+
statusBarBackgroundActivity = null
|
|
187
|
+
navBarBackgroundView = null
|
|
188
|
+
isEdgeToEdgeActive = false
|
|
189
|
+
isThreeButtonNav = false
|
|
190
|
+
lastExplicitNavBarColor = null
|
|
191
|
+
statusBarHeight = -1
|
|
72
192
|
}
|
|
73
193
|
|
|
194
|
+
// endregion
|
|
195
|
+
|
|
196
|
+
// region Status Bar
|
|
197
|
+
|
|
74
198
|
@JvmStatic
|
|
75
199
|
fun setStatusBarColorScheme(window: Window?, view: View, isDark: Boolean) {
|
|
76
200
|
window?.let {
|
|
77
201
|
WindowInsetsControllerCompat(window, view).isAppearanceLightStatusBars = isDark
|
|
78
|
-
// Workaround: on devices with api 30 status bar icons flickers or get hidden when removing view
|
|
79
|
-
//turns out it is a bug on such devices, fixed by using system flags until it is fixed.
|
|
80
|
-
var flags = view.systemUiVisibility
|
|
81
|
-
flags = if (isDark) {
|
|
82
|
-
flags or View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
|
|
83
|
-
} else {
|
|
84
|
-
flags and View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR.inv()
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
view.systemUiVisibility = flags
|
|
88
202
|
}
|
|
89
203
|
}
|
|
90
204
|
|
|
91
205
|
@JvmStatic
|
|
92
206
|
fun setStatusBarTranslucent(window: Window?) {
|
|
93
|
-
window?.let {
|
|
94
|
-
setStatusBarColor(window,
|
|
207
|
+
getStatusBarColor(window)?.let { currentColor ->
|
|
208
|
+
setStatusBarColor(window, currentColor, true)
|
|
95
209
|
}
|
|
96
210
|
}
|
|
97
211
|
|
|
98
212
|
@JvmStatic
|
|
99
213
|
fun isTranslucent(window: Window?): Boolean {
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
} ?: false
|
|
214
|
+
val color = getStatusBarColor(window) ?: return false
|
|
215
|
+
return Color.alpha(color) < 255
|
|
103
216
|
}
|
|
104
217
|
|
|
105
218
|
@JvmStatic
|
|
106
219
|
fun clearStatusBarTranslucency(window: Window?) {
|
|
107
|
-
window?.let {
|
|
108
|
-
setStatusBarColor(
|
|
220
|
+
getStatusBarColor(window)?.let { currentColor ->
|
|
221
|
+
setStatusBarColor(window, currentColor, false)
|
|
109
222
|
}
|
|
110
223
|
}
|
|
111
224
|
|
|
112
225
|
@JvmStatic
|
|
113
|
-
fun setStatusBarColor(
|
|
114
|
-
window: Window?,
|
|
115
|
-
@ColorInt color: Int,
|
|
116
|
-
translucent: Boolean
|
|
117
|
-
) {
|
|
226
|
+
fun setStatusBarColor(window: Window?, @ColorInt color: Int, translucent: Boolean) {
|
|
118
227
|
val colorAlpha = Color.alpha(color)
|
|
119
|
-
val alpha = if (translucent && colorAlpha == 255) STATUS_BAR_HEIGHT_TRANSLUCENCY else colorAlpha/255.0f
|
|
120
|
-
val
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
228
|
+
val alpha = if (translucent && colorAlpha == 255) STATUS_BAR_HEIGHT_TRANSLUCENCY else colorAlpha / 255.0f
|
|
229
|
+
val opaqueColor = Color.argb(
|
|
230
|
+
ceil(alpha * 255).toInt(),
|
|
231
|
+
Color.red(color),
|
|
232
|
+
Color.green(color),
|
|
233
|
+
Color.blue(color)
|
|
234
|
+
)
|
|
235
|
+
applyStatusBarColor(window, opaqueColor)
|
|
125
236
|
}
|
|
126
237
|
|
|
238
|
+
/**
|
|
239
|
+
* Sets the status bar background color, lazily creating a manual view on API 35+
|
|
240
|
+
* if the system view wasn't available at setup time. Use this for explicit app-level
|
|
241
|
+
* color requests (e.g. from MainActivity or NavigationActivity).
|
|
242
|
+
*/
|
|
243
|
+
@JvmStatic
|
|
127
244
|
fun setStatusBarColor(window: Window?, color: Int) {
|
|
128
|
-
|
|
245
|
+
val view = ensureStatusBarBackgroundView()
|
|
246
|
+
if (view != null) {
|
|
247
|
+
view.setBackgroundColor(color)
|
|
248
|
+
} else {
|
|
249
|
+
@Suppress("DEPRECATION")
|
|
250
|
+
window?.statusBarColor = color
|
|
251
|
+
}
|
|
129
252
|
}
|
|
130
253
|
|
|
254
|
+
private fun applyStatusBarColor(window: Window?, color: Int) {
|
|
255
|
+
statusBarBackgroundView?.setBackgroundColor(color) ?: run {
|
|
256
|
+
@Suppress("DEPRECATION")
|
|
257
|
+
window?.statusBarColor = color
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* Gets the current status bar background color.
|
|
263
|
+
* Reads from the view-based background when available,
|
|
264
|
+
* falls back to the deprecated window API on older configurations.
|
|
265
|
+
*/
|
|
131
266
|
@JvmStatic
|
|
132
267
|
fun getStatusBarColor(window: Window?): Int? {
|
|
268
|
+
statusBarBackgroundView?.let { view ->
|
|
269
|
+
(view.background as? ColorDrawable)?.let { return it.color }
|
|
270
|
+
}
|
|
271
|
+
@Suppress("DEPRECATION")
|
|
133
272
|
return window?.statusBarColor
|
|
134
273
|
}
|
|
135
274
|
|
|
136
275
|
@JvmStatic
|
|
137
276
|
fun hideStatusBar(window: Window?, view: View) {
|
|
138
277
|
window?.let {
|
|
139
|
-
WindowCompat.setDecorFitsSystemWindows(window, false)
|
|
140
278
|
WindowInsetsControllerCompat(window, view).let { controller ->
|
|
141
279
|
controller.hide(WindowInsetsCompat.Type.statusBars())
|
|
142
280
|
controller.systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
|
|
@@ -147,22 +285,49 @@ object SystemUiUtils {
|
|
|
147
285
|
@JvmStatic
|
|
148
286
|
fun showStatusBar(window: Window?, view: View) {
|
|
149
287
|
window?.let {
|
|
150
|
-
WindowCompat.setDecorFitsSystemWindows(window, true)
|
|
151
288
|
WindowInsetsControllerCompat(window, view).show(WindowInsetsCompat.Type.statusBars())
|
|
152
289
|
}
|
|
153
290
|
}
|
|
154
291
|
|
|
292
|
+
// endregion
|
|
293
|
+
|
|
294
|
+
// region Navigation Bar
|
|
295
|
+
|
|
155
296
|
@JvmStatic
|
|
156
|
-
fun
|
|
297
|
+
fun hideNavigationBar(window: Window?, view: View) {
|
|
157
298
|
window?.let {
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
WindowInsetsControllerCompat(window, window.decorView).let { controller ->
|
|
162
|
-
controller.isAppearanceLightNavigationBars = lightColor
|
|
299
|
+
WindowInsetsControllerCompat(window, view).let { controller ->
|
|
300
|
+
controller.hide(WindowInsetsCompat.Type.navigationBars())
|
|
301
|
+
controller.systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
|
|
163
302
|
}
|
|
164
|
-
window.navigationBarColor = color
|
|
165
303
|
}
|
|
166
304
|
}
|
|
167
305
|
|
|
306
|
+
@JvmStatic
|
|
307
|
+
fun showNavigationBar(window: Window?, view: View) {
|
|
308
|
+
window?.let {
|
|
309
|
+
WindowInsetsControllerCompat(window, view).show(WindowInsetsCompat.Type.navigationBars())
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
/**
|
|
314
|
+
* Sets the navigation bar background color and icon appearance.
|
|
315
|
+
* Uses the view-based background when available (edge-to-edge),
|
|
316
|
+
* falls back to the deprecated window API on older configurations.
|
|
317
|
+
*/
|
|
318
|
+
@JvmStatic
|
|
319
|
+
fun setNavigationBarBackgroundColor(window: Window?, color: Int, lightColor: Boolean) {
|
|
320
|
+
lastExplicitNavBarColor = color
|
|
321
|
+
window?.let {
|
|
322
|
+
WindowInsetsControllerCompat(window, window.decorView).isAppearanceLightNavigationBars = lightColor
|
|
323
|
+
}
|
|
324
|
+
if (isEdgeToEdgeActive) {
|
|
325
|
+
navBarBackgroundView?.setBackgroundColor(color)
|
|
326
|
+
} else {
|
|
327
|
+
@Suppress("DEPRECATION")
|
|
328
|
+
window?.navigationBarColor = color
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
// endregion
|
|
168
333
|
}
|
|
@@ -254,12 +254,13 @@ public class BottomTabsController extends ParentController<BottomTabsLayout> imp
|
|
|
254
254
|
|
|
255
255
|
@Override
|
|
256
256
|
public int getBottomInset(ViewController<?> child) {
|
|
257
|
-
return presenter.
|
|
257
|
+
return presenter.getChildrenBottomInset(resolveChildOptions(child)) + perform(getParentController(), 0, p -> p.getBottomInset(this));
|
|
258
258
|
}
|
|
259
259
|
|
|
260
260
|
@Override
|
|
261
261
|
public void applyBottomInset() {
|
|
262
|
-
presenter.
|
|
262
|
+
presenter.applyChildrenInset(getBottomInset());
|
|
263
|
+
presenter.applySelfInset(getBottomInset());
|
|
263
264
|
super.applyBottomInset();
|
|
264
265
|
}
|
|
265
266
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
package com.reactnativenavigation.viewcontrollers.bottomtabs
|
|
2
2
|
|
|
3
3
|
import android.animation.Animator
|
|
4
|
+
import android.app.Activity
|
|
4
5
|
import android.graphics.Color
|
|
5
6
|
import android.view.ViewGroup
|
|
6
7
|
import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
|
|
@@ -12,6 +13,8 @@ import com.reactnativenavigation.RNNToggles.TAB_BAR_TRANSLUCENCE
|
|
|
12
13
|
import com.reactnativenavigation.options.Options
|
|
13
14
|
import com.reactnativenavigation.options.params.BottomTabsLayoutStyle
|
|
14
15
|
import com.reactnativenavigation.options.params.Fraction
|
|
16
|
+
import com.reactnativenavigation.utils.ColorUtils.isColorLight
|
|
17
|
+
import com.reactnativenavigation.utils.SystemUiUtils
|
|
15
18
|
import com.reactnativenavigation.utils.UiUtils
|
|
16
19
|
import com.reactnativenavigation.viewcontrollers.viewcontroller.ViewController
|
|
17
20
|
import com.reactnativenavigation.views.bottomtabs.BottomTabs
|
|
@@ -92,7 +95,9 @@ class BottomTabsPresenter(
|
|
|
92
95
|
|
|
93
96
|
// Keep this before the translucent check below
|
|
94
97
|
if (bottomTabsOptions.backgroundColor.hasValue()) {
|
|
95
|
-
|
|
98
|
+
val color = bottomTabsOptions.backgroundColor.get()
|
|
99
|
+
bottomTabsContainer.setBackgroundColor(color)
|
|
100
|
+
syncNavigationBarColor(options, color)
|
|
96
101
|
}
|
|
97
102
|
|
|
98
103
|
if (RNNFeatureToggles.isEnabled(TAB_BAR_TRANSLUCENCE)) {
|
|
@@ -212,7 +217,9 @@ class BottomTabsPresenter(
|
|
|
212
217
|
bottomTabsContainer.enableBackgroundBlur()
|
|
213
218
|
} else {
|
|
214
219
|
bottomTabsContainer.disableBackgroundBlur()
|
|
215
|
-
|
|
220
|
+
val color = bottomTabsOptions.backgroundColor.get(Color.WHITE)!!
|
|
221
|
+
bottomTabsContainer.setBackgroundColor(color)
|
|
222
|
+
syncNavigationBarColor(options, color)
|
|
216
223
|
}
|
|
217
224
|
|
|
218
225
|
bottomTabs.setLayoutDirection(options.layout.direction)
|
|
@@ -282,13 +289,17 @@ class BottomTabsPresenter(
|
|
|
282
289
|
bottomTabs.setBehaviorTranslationEnabled(bottomTabsOptions.hideOnScroll[false])
|
|
283
290
|
}
|
|
284
291
|
|
|
285
|
-
fun
|
|
292
|
+
fun applyChildrenInset(bottomInset: Int) {
|
|
286
293
|
(bottomTabsContainer.layoutParams as ViewGroup.MarginLayoutParams).updateMargins(bottom = bottomInset)
|
|
287
294
|
bottomTabsContainer.requestLayout()
|
|
288
295
|
}
|
|
289
296
|
|
|
290
|
-
fun
|
|
291
|
-
return if (resolvedOptions.withDefaultOptions(defaultOptions).bottomTabsOptions.isHiddenOrDrawBehind) 0 else
|
|
297
|
+
fun getChildrenBottomInset(resolvedOptions: Options): Int {
|
|
298
|
+
return if (resolvedOptions.withDefaultOptions(defaultOptions).bottomTabsOptions.isHiddenOrDrawBehind) 0 else (bottomTabsContainer.height)
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
fun applySelfInset(bottomInset: Int) {
|
|
302
|
+
bottomTabsContainer.setBottomInset(bottomInset)
|
|
292
303
|
}
|
|
293
304
|
|
|
294
305
|
fun getPushAnimation(appearingOptions: Options): Animator? {
|
|
@@ -351,7 +362,9 @@ class BottomTabsPresenter(
|
|
|
351
362
|
bottomTabsContainer.disableBackgroundBlur()
|
|
352
363
|
|
|
353
364
|
// TODO Change to bottomTabsContainer.setBackgroundColor()?
|
|
354
|
-
|
|
365
|
+
val color = bottomTabsOptions.backgroundColor.get(Color.WHITE)!!
|
|
366
|
+
bottomTabs.setBackgroundColor(color)
|
|
367
|
+
syncNavigationBarColor(options, color)
|
|
355
368
|
}
|
|
356
369
|
|
|
357
370
|
if (bottomTabsOptions.shadowOptions.hasValue()) {
|
|
@@ -376,4 +389,11 @@ class BottomTabsPresenter(
|
|
|
376
389
|
val margin = UiUtils.dpToPx(bottomTabsContainer.context, marginDp.toFloat()).roundToInt()
|
|
377
390
|
return margin
|
|
378
391
|
}
|
|
392
|
+
|
|
393
|
+
private fun syncNavigationBarColor(options: Options, tabsColor: Int) {
|
|
394
|
+
val resolved = options.copy().withDefaultOptions(defaultOptions)
|
|
395
|
+
if (resolved.navigationBar.backgroundColor.hasValue()) return
|
|
396
|
+
val window = (bottomTabsContainer.context as? Activity)?.window ?: return
|
|
397
|
+
SystemUiUtils.setNavigationBarBackgroundColor(window, tabsColor, isColorLight(tabsColor))
|
|
398
|
+
}
|
|
379
399
|
}
|
|
@@ -172,9 +172,12 @@ public class ComponentViewController extends ChildController<ComponentLayout> {
|
|
|
172
172
|
int systemWindowInsetTop = insets.getInsets(WindowInsetsCompat.Type.statusBars()).top +
|
|
173
173
|
insets.getInsets(WindowInsetsCompat.Type.navigationBars()).top -
|
|
174
174
|
systemBarsInsets.top;
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
175
|
+
|
|
176
|
+
int navBarBottom = insets.getInsets(WindowInsetsCompat.Type.navigationBars()).bottom;
|
|
177
|
+
int imeBottom = insets.getInsets(WindowInsetsCompat.Type.ime()).bottom;
|
|
178
|
+
int systemWindowInsetBottom = SystemUiUtils.isEdgeToEdgeActive()
|
|
179
|
+
? Math.max(imeBottom, navBarBottom)
|
|
180
|
+
: imeBottom;
|
|
178
181
|
|
|
179
182
|
WindowInsetsCompat finalInsets = new WindowInsetsCompat.Builder()
|
|
180
183
|
.setInsets(WindowInsetsCompat.Type.systemBars() | WindowInsetsCompat.Type.ime(),
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
package com.reactnativenavigation.viewcontrollers.viewcontroller
|
|
2
2
|
|
|
3
3
|
import android.annotation.SuppressLint
|
|
4
|
-
import com.facebook.react.ReactInstanceManager
|
|
5
4
|
import com.facebook.react.modules.i18nmanager.I18nUtil
|
|
6
5
|
import com.reactnativenavigation.options.Options
|
|
7
6
|
|
|
@@ -16,4 +15,4 @@ class LayoutDirectionApplier {
|
|
|
16
15
|
I18nUtil.instance.forceRTL(currentContext, options.layout.direction.isRtl)
|
|
17
16
|
}
|
|
18
17
|
}
|
|
19
|
-
}
|
|
18
|
+
}
|
|
@@ -136,14 +136,12 @@ public class Presenter {
|
|
|
136
136
|
}
|
|
137
137
|
|
|
138
138
|
private void setNavigationBarBackgroundColor(NavigationBarOptions navigationBar) {
|
|
139
|
-
int
|
|
140
|
-
navigationBarDefaultColor = navigationBarDefaultColor == -1 ? Color.BLACK : navigationBarDefaultColor;
|
|
139
|
+
int defaultColor = SystemUiUtils.getDefaultNavBarColor();
|
|
141
140
|
if (navigationBar.backgroundColor.canApplyValue()) {
|
|
142
|
-
int color = navigationBar.backgroundColor.get(
|
|
141
|
+
int color = navigationBar.backgroundColor.get(defaultColor);
|
|
143
142
|
SystemUiUtils.setNavigationBarBackgroundColor(activity.getWindow(), color, isColorLight(color));
|
|
144
143
|
} else {
|
|
145
|
-
SystemUiUtils.setNavigationBarBackgroundColor(activity.getWindow(),
|
|
146
|
-
|
|
144
|
+
SystemUiUtils.setNavigationBarBackgroundColor(activity.getWindow(), defaultColor, isColorLight(defaultColor));
|
|
147
145
|
}
|
|
148
146
|
}
|
|
149
147
|
|
|
@@ -430,17 +430,13 @@ public abstract class ViewController<T extends ViewGroup> implements ViewTreeObs
|
|
|
430
430
|
return false;
|
|
431
431
|
}
|
|
432
432
|
|
|
433
|
-
public void applyTopInset() {
|
|
434
|
-
|
|
435
|
-
}
|
|
433
|
+
public void applyTopInset() {}
|
|
436
434
|
|
|
437
435
|
public int getTopInset() {
|
|
438
436
|
return 0;
|
|
439
437
|
}
|
|
440
438
|
|
|
441
|
-
public void applyBottomInset() {
|
|
442
|
-
|
|
443
|
-
}
|
|
439
|
+
public void applyBottomInset() {}
|
|
444
440
|
|
|
445
441
|
public int getBottomInset() {
|
|
446
442
|
return perform(parentController, 0, p -> p.getBottomInset(this));
|
package/android/src/main/java/com/reactnativenavigation/views/bottomtabs/BottomTabsContainer.kt
CHANGED
|
@@ -12,6 +12,7 @@ import android.widget.FrameLayout.LayoutParams.WRAP_CONTENT
|
|
|
12
12
|
import android.widget.LinearLayout
|
|
13
13
|
import androidx.annotation.RestrictTo
|
|
14
14
|
import androidx.core.graphics.ColorUtils
|
|
15
|
+
import androidx.core.view.updatePadding
|
|
15
16
|
import com.reactnativenavigation.options.params.Fraction
|
|
16
17
|
import com.reactnativenavigation.utils.UiUtils.dpToPx
|
|
17
18
|
import eightbitlab.com.blurview.BlurTarget
|
|
@@ -176,4 +177,8 @@ class BottomTabsContainer(context: Context, val bottomTabs: BottomTabs) : Shadow
|
|
|
176
177
|
fun setElevation(elevation: Fraction) {
|
|
177
178
|
setElevation(dpToPx(context, elevation.get().toFloat()))
|
|
178
179
|
}
|
|
180
|
+
|
|
181
|
+
fun setBottomInset(bottomInset: Int) {
|
|
182
|
+
blurringView.updatePadding(bottom = bottomInset)
|
|
183
|
+
}
|
|
179
184
|
}
|
|
@@ -8,8 +8,15 @@
|
|
|
8
8
|
|
|
9
9
|
- (void)applyBackgroundColor:(UIColor *)backgroundColor translucent:(BOOL)translucent {
|
|
10
10
|
if (@available(iOS 26.0, *)) {
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
if (backgroundColor) {
|
|
12
|
+
if (backgroundColor.isTransparent) {
|
|
13
|
+
[self setTabBarTransparentBackground];
|
|
14
|
+
} else {
|
|
15
|
+
[self setTabBarBackgroundColor:backgroundColor];
|
|
16
|
+
}
|
|
17
|
+
} else {
|
|
18
|
+
[self setTabBarDefaultBackground];
|
|
19
|
+
}
|
|
13
20
|
return;
|
|
14
21
|
}
|
|
15
22
|
if (translucent)
|
|
@@ -61,8 +68,9 @@
|
|
|
61
68
|
|
|
62
69
|
- (void)setTabBarDefaultBackground {
|
|
63
70
|
if (@available(iOS 26.0, *)) {
|
|
64
|
-
[
|
|
65
|
-
|
|
71
|
+
UITabBarAppearance *appearance = [UITabBarAppearance new];
|
|
72
|
+
[appearance configureWithDefaultBackground];
|
|
73
|
+
[self applyTabBarAppearance:appearance];
|
|
66
74
|
} else {
|
|
67
75
|
[self setTabBarOpaqueBackground];
|
|
68
76
|
}
|
|
@@ -95,7 +103,11 @@
|
|
|
95
103
|
|
|
96
104
|
- (UITabBarAppearance *)appearanceWithColor:(UIColor *)color {
|
|
97
105
|
UITabBarAppearance *appearance = [UITabBarAppearance new];
|
|
98
|
-
|
|
106
|
+
if (@available(iOS 26.0, *)) {
|
|
107
|
+
[appearance configureWithTransparentBackground];
|
|
108
|
+
} else {
|
|
109
|
+
[appearance configureWithOpaqueBackground];
|
|
110
|
+
}
|
|
99
111
|
appearance.backgroundEffect = nil;
|
|
100
112
|
appearance.shadowColor = nil;
|
|
101
113
|
UIColor *resolvedColor = color ?: UIColor.systemBackgroundColor;
|
|
@@ -51,12 +51,9 @@
|
|
|
51
51
|
|
|
52
52
|
if (@available(iOS 26.0, *)) {
|
|
53
53
|
UITabBarAppearance *appearance = [UITabBarAppearance new];
|
|
54
|
-
[appearance
|
|
55
|
-
appearance.backgroundEffect = nil;
|
|
56
|
-
appearance.backgroundColor = UIColor.clearColor;
|
|
54
|
+
[appearance configureWithDefaultBackground];
|
|
57
55
|
self.tabBar.standardAppearance = appearance;
|
|
58
56
|
self.tabBar.scrollEdgeAppearance = [appearance copy];
|
|
59
|
-
self.tabBar.barTintColor = UIColor.clearColor;
|
|
60
57
|
} else if (@available(iOS 13.0, *)) {
|
|
61
58
|
UITabBarAppearance *appearance = [UITabBarAppearance new];
|
|
62
59
|
[appearance configureWithOpaqueBackground];
|
|
@@ -118,14 +118,18 @@ static NSString *const setDefaultOptions = @"setDefaultOptions";
|
|
|
118
118
|
|
|
119
119
|
UIViewController<RNNLayoutProtocol> *vc = [_layoutManager findComponentForId:componentId];
|
|
120
120
|
RNNNavigationOptions *newOptions = [[RNNNavigationOptions alloc] initWithDict:mergeOptions];
|
|
121
|
-
if ([vc conformsToProtocol:@protocol(RNNLayoutProtocol)] ||
|
|
122
|
-
|
|
121
|
+
if (vc && ([vc conformsToProtocol:@protocol(RNNLayoutProtocol)] ||
|
|
122
|
+
[vc isKindOfClass:[RNNComponentViewController class]])) {
|
|
123
123
|
[CATransaction begin];
|
|
124
124
|
[CATransaction setCompletionBlock:completion];
|
|
125
125
|
|
|
126
126
|
[vc mergeOptions:newOptions];
|
|
127
127
|
|
|
128
128
|
[CATransaction commit];
|
|
129
|
+
} else {
|
|
130
|
+
if (completion) {
|
|
131
|
+
completion();
|
|
132
|
+
}
|
|
129
133
|
}
|
|
130
134
|
}
|
|
131
135
|
|
|
@@ -324,10 +328,10 @@ static NSString *const setDefaultOptions = @"setDefaultOptions";
|
|
|
324
328
|
|
|
325
329
|
RNNComponentViewController *vc =
|
|
326
330
|
(RNNComponentViewController *)[_layoutManager findComponentForId:componentId];
|
|
327
|
-
RNNNavigationOptions *options = [[RNNNavigationOptions alloc] initWithDict:mergeOptions];
|
|
328
|
-
[vc mergeOptions:options];
|
|
329
|
-
|
|
330
331
|
if (vc) {
|
|
332
|
+
RNNNavigationOptions *options = [[RNNNavigationOptions alloc] initWithDict:mergeOptions];
|
|
333
|
+
[vc mergeOptions:options];
|
|
334
|
+
|
|
331
335
|
[vc.stack popTo:vc
|
|
332
336
|
animated:[vc.resolveOptionsWithDefault.animations.pop.enable withDefault:YES]
|
|
333
337
|
completion:^(NSArray *poppedViewControllers) {
|
|
@@ -355,25 +359,27 @@ static NSString *const setDefaultOptions = @"setDefaultOptions";
|
|
|
355
359
|
|
|
356
360
|
RNNComponentViewController *vc =
|
|
357
361
|
(RNNComponentViewController *)[_layoutManager findComponentForId:componentId];
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
[CATransaction begin];
|
|
362
|
-
[CATransaction setCompletionBlock:^{
|
|
363
|
-
[self->_eventEmitter sendOnNavigationCommandCompletion:popToRoot commandId:commandId];
|
|
364
|
-
completion();
|
|
365
|
-
}];
|
|
366
|
-
|
|
367
|
-
[vc.stack popToRoot:vc
|
|
368
|
-
animated:[vc.resolveOptionsWithDefault.animations.pop.enable withDefault:YES]
|
|
369
|
-
completion:^(NSArray *poppedViewControllers) {
|
|
370
|
-
|
|
371
|
-
}
|
|
372
|
-
rejection:^(NSString *code, NSString *message, NSError *error){
|
|
373
|
-
|
|
374
|
-
}];
|
|
362
|
+
if (vc) {
|
|
363
|
+
RNNNavigationOptions *options = [[RNNNavigationOptions alloc] initWithDict:mergeOptions];
|
|
364
|
+
[vc mergeOptions:options];
|
|
375
365
|
|
|
376
|
-
|
|
366
|
+
[vc.stack popToRoot:vc
|
|
367
|
+
animated:[vc.resolveOptionsWithDefault.animations.pop.enable withDefault:YES]
|
|
368
|
+
completion:^(NSArray *poppedViewControllers) {
|
|
369
|
+
[self->_eventEmitter sendOnNavigationCommandCompletion:popToRoot
|
|
370
|
+
commandId:commandId];
|
|
371
|
+
completion();
|
|
372
|
+
}
|
|
373
|
+
rejection:rejection];
|
|
374
|
+
} else {
|
|
375
|
+
[RNNErrorHandler
|
|
376
|
+
reject:rejection
|
|
377
|
+
withErrorCode:1012
|
|
378
|
+
errorDescription:
|
|
379
|
+
[NSString stringWithFormat:
|
|
380
|
+
@"PopToRoot component failed - componentId '%@' not found",
|
|
381
|
+
componentId]];
|
|
382
|
+
}
|
|
377
383
|
}
|
|
378
384
|
|
|
379
385
|
- (void)showModal:(NSDictionary *)layout
|
package/ios/RNNOverlayManager.mm
CHANGED
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
[overlayWindow setHidden:NO];
|
|
20
20
|
|
|
21
21
|
overlayWindow.previousWindow.accessibilityElementsHidden = YES;
|
|
22
|
+
UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification, overlayWindow);
|
|
22
23
|
}
|
|
23
24
|
|
|
24
25
|
- (void)showOverlayWindowAsKeyWindow:(RNNOverlayWindow *)overlayWindow {
|
|
@@ -41,6 +42,7 @@
|
|
|
41
42
|
|
|
42
43
|
- (void)detachOverlayWindow:(RNNOverlayWindow *)overlayWindow {
|
|
43
44
|
overlayWindow.previousWindow.accessibilityElementsHidden = NO;
|
|
45
|
+
UIAccessibilityPostNotification(UIAccessibilityLayoutChangedNotification, nil);
|
|
44
46
|
|
|
45
47
|
[overlayWindow.previousWindow makeKeyWindow];
|
|
46
48
|
[overlayWindow setHidden:YES];
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
package com.reactnativenavigation.viewcontrollers.statusbar
|
|
2
|
+
|
|
3
|
+
import android.animation.Animator
|
|
4
|
+
import android.app.Activity
|
|
5
|
+
import android.graphics.Color
|
|
6
|
+
import android.view.View
|
|
7
|
+
import android.view.Window
|
|
8
|
+
import com.reactnativenavigation.RNNFeatureToggles.isEnabled
|
|
9
|
+
import com.reactnativenavigation.RNNToggles
|
|
10
|
+
import com.reactnativenavigation.options.Options
|
|
11
|
+
import com.reactnativenavigation.options.StatusBarOptions
|
|
12
|
+
import com.reactnativenavigation.options.StatusBarOptions.TextColorScheme
|
|
13
|
+
import com.reactnativenavigation.options.params.Bool
|
|
14
|
+
import com.reactnativenavigation.utils.ColorUtils.isColorLight
|
|
15
|
+
import com.reactnativenavigation.utils.StubAnimationListener.Companion.onAnimatorEnd
|
|
16
|
+
import com.reactnativenavigation.utils.SystemUiUtils.clearStatusBarTranslucency
|
|
17
|
+
import com.reactnativenavigation.utils.SystemUiUtils.getStatusBarColor
|
|
18
|
+
import com.reactnativenavigation.utils.SystemUiUtils.hideStatusBar
|
|
19
|
+
import com.reactnativenavigation.utils.SystemUiUtils.isTranslucent
|
|
20
|
+
import com.reactnativenavigation.utils.SystemUiUtils.setStatusBarColor
|
|
21
|
+
import com.reactnativenavigation.utils.SystemUiUtils.setStatusBarColorScheme
|
|
22
|
+
import com.reactnativenavigation.utils.SystemUiUtils.setStatusBarTranslucent
|
|
23
|
+
import com.reactnativenavigation.utils.SystemUiUtils.showStatusBar
|
|
24
|
+
import com.reactnativenavigation.viewcontrollers.viewcontroller.StatusBarColorAnimator
|
|
25
|
+
import com.reactnativenavigation.viewcontrollers.viewcontroller.ViewController
|
|
26
|
+
import java.lang.ref.WeakReference
|
|
27
|
+
|
|
28
|
+
class StatusBarPresenter private constructor(
|
|
29
|
+
activity: Activity,
|
|
30
|
+
private val sbColorAnimator: StatusBarColorAnimator = StatusBarColorAnimator(activity)) {
|
|
31
|
+
|
|
32
|
+
private val window = WeakReference(activity.window)
|
|
33
|
+
private var hasPendingColorAnim = false
|
|
34
|
+
|
|
35
|
+
fun applyOptions(viewController: ViewController<*>, options: StatusBarOptions) {
|
|
36
|
+
if (!hasPendingColorAnim) {
|
|
37
|
+
setStatusBarBackgroundColor(options)
|
|
38
|
+
setTranslucent(options)
|
|
39
|
+
}
|
|
40
|
+
setTextColorScheme(options)
|
|
41
|
+
setStatusBarVisible(viewController, options.visible)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
fun mergeOptions(view: View, statusBar: StatusBarOptions) {
|
|
45
|
+
mergeStatusBarBackgroundColor(statusBar)
|
|
46
|
+
mergeTextColorScheme(statusBar)
|
|
47
|
+
mergeTranslucent(statusBar)
|
|
48
|
+
mergeStatusBarVisible(view, statusBar.visible)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
fun onConfigurationChanged(options: StatusBarOptions) {
|
|
52
|
+
setStatusBarBackgroundColor(options)
|
|
53
|
+
setTextColorScheme(options)
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
fun bindViewController(newOptions: StatusBarOptions) {
|
|
57
|
+
if (!isEnabled(RNNToggles.TOP_BAR_COLOR_ANIMATION__TABS)) {
|
|
58
|
+
return
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (newOptions.backgroundColor.canApplyValue()) {
|
|
62
|
+
val currentColor = getCurrentStatusBarBackgroundColor() ?: return
|
|
63
|
+
val newColor = getStatusBarBackgroundColor(newOptions)
|
|
64
|
+
createStatusBarColorAnimation(
|
|
65
|
+
from = currentColor,
|
|
66
|
+
to = newColor,
|
|
67
|
+
translucent = newOptions.translucent.isTrue,
|
|
68
|
+
).start()
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
fun getStatusBarPushAnimation(appearingOptions: Options): Animator? =
|
|
73
|
+
if (isEnabled(RNNToggles.TOP_BAR_COLOR_ANIMATION__PUSH)) {
|
|
74
|
+
getStatusBarColorAnimation(appearingOptions.statusBar)
|
|
75
|
+
} else null
|
|
76
|
+
|
|
77
|
+
fun getStatusBarPopAnimation(appearingOptions: Options, disappearingOptions: Options): Animator? =
|
|
78
|
+
if (isEnabled(RNNToggles.TOP_BAR_COLOR_ANIMATION__PUSH)) {
|
|
79
|
+
getStatusBarColorAnimation(appearingOptions.statusBar)
|
|
80
|
+
} else null
|
|
81
|
+
|
|
82
|
+
private fun setStatusBarBackgroundColor(statusBar: StatusBarOptions) {
|
|
83
|
+
if (statusBar.backgroundColor.canApplyValue()) {
|
|
84
|
+
val statusBarBackgroundColor: Int = getStatusBarBackgroundColor(statusBar)
|
|
85
|
+
setStatusBarBackgroundColor(statusBarBackgroundColor, statusBar.translucent.isTrue)
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
private fun setStatusBarBackgroundColor(color: Int, translucent: Boolean) {
|
|
90
|
+
setStatusBarColor(window.get(), color, translucent)
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
private fun getStatusBarBackgroundColor(statusBar: StatusBarOptions): Int {
|
|
94
|
+
val defaultColor =
|
|
95
|
+
if (statusBar.visible.isTrueOrUndefined) Color.BLACK else Color.TRANSPARENT
|
|
96
|
+
return statusBar.backgroundColor.get(defaultColor)!!
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
private fun setTextColorScheme(statusBar: StatusBarOptions) {
|
|
100
|
+
val view = window.get()?.decorView
|
|
101
|
+
//View.post is a Workaround, added to solve internal Samsung
|
|
102
|
+
//Android 9 issues. For more info see https://github.com/wix/react-native-navigation/pull/7231
|
|
103
|
+
view?.post {
|
|
104
|
+
setStatusBarColorScheme(
|
|
105
|
+
window.get(),
|
|
106
|
+
view,
|
|
107
|
+
isDarkTextColorScheme(statusBar)
|
|
108
|
+
)
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
private fun setTranslucent(options: StatusBarOptions) {
|
|
113
|
+
val window = window.get()
|
|
114
|
+
if (options.translucent.isTrue) {
|
|
115
|
+
setStatusBarTranslucent(window)
|
|
116
|
+
} else if (isTranslucent(window)) {
|
|
117
|
+
clearStatusBarTranslucency(window)
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
private fun setStatusBarVisible(viewController: ViewController<*>, visible: Bool) {
|
|
122
|
+
val window = window.get() ?: return
|
|
123
|
+
val view = if (viewController.view != null) viewController.view else window.decorView
|
|
124
|
+
if (visible.isFalse) {
|
|
125
|
+
hideStatusBar(window, view)
|
|
126
|
+
} else {
|
|
127
|
+
showStatusBar(window, view)
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
private fun mergeStatusBarBackgroundColor(statusBar: StatusBarOptions) {
|
|
132
|
+
if (statusBar.backgroundColor.hasValue()) {
|
|
133
|
+
val statusBarBackgroundColor = getStatusBarBackgroundColor(statusBar)
|
|
134
|
+
setStatusBarColor(
|
|
135
|
+
window.get(), statusBarBackgroundColor,
|
|
136
|
+
statusBar.translucent.isTrue
|
|
137
|
+
)
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
private fun mergeTextColorScheme(statusBar: StatusBarOptions) {
|
|
142
|
+
if (!statusBar.textColorScheme.hasValue()) return
|
|
143
|
+
setTextColorScheme(statusBar)
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
private fun mergeTranslucent(options: StatusBarOptions) {
|
|
147
|
+
val window: Window = window.get() ?: return
|
|
148
|
+
if (options.translucent.isTrue) {
|
|
149
|
+
setStatusBarTranslucent(window)
|
|
150
|
+
} else if (options.translucent.isFalse && isTranslucent(window)) {
|
|
151
|
+
clearStatusBarTranslucency(window)
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
private fun mergeStatusBarVisible(view: View, visible: Bool) {
|
|
156
|
+
if (visible.hasValue()) {
|
|
157
|
+
if (visible.isTrue) {
|
|
158
|
+
showStatusBar(window.get(), view)
|
|
159
|
+
} else {
|
|
160
|
+
hideStatusBar(window.get(), view)
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
private fun isDarkTextColorScheme(statusBar: StatusBarOptions): Boolean {
|
|
166
|
+
if (statusBar.textColorScheme == TextColorScheme.Dark) {
|
|
167
|
+
return true
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
if (statusBar.textColorScheme == TextColorScheme.Light) {
|
|
171
|
+
return false
|
|
172
|
+
}
|
|
173
|
+
return isColorLight(getStatusBarBackgroundColor(statusBar))
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
private fun getStatusBarColorAnimation(statusBarOptions: StatusBarOptions): Animator? {
|
|
177
|
+
if (isEnabled(RNNToggles.TOP_BAR_COLOR_ANIMATION__TABS)) {
|
|
178
|
+
getCurrentStatusBarBackgroundColor()?.let { currentColor ->
|
|
179
|
+
val targetColor = statusBarOptions.backgroundColor
|
|
180
|
+
|
|
181
|
+
if (targetColor.hasValue()) {
|
|
182
|
+
val translucent = statusBarOptions.translucent.isTrue
|
|
183
|
+
return createStatusBarColorAnimation(
|
|
184
|
+
from = currentColor,
|
|
185
|
+
to = targetColor.get(),
|
|
186
|
+
translucent = translucent,
|
|
187
|
+
)
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
return null
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
private fun createStatusBarColorAnimation(from: Int, to: Int, translucent: Boolean): Animator =
|
|
195
|
+
sbColorAnimator.getAnimator(from, to, translucent).apply {
|
|
196
|
+
addListener(onAnimatorEnd {
|
|
197
|
+
hasPendingColorAnim = false
|
|
198
|
+
})
|
|
199
|
+
hasPendingColorAnim = true
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
private fun getCurrentStatusBarBackgroundColor() =
|
|
203
|
+
getStatusBarColor(window.get())
|
|
204
|
+
|
|
205
|
+
companion object {
|
|
206
|
+
lateinit var instance: StatusBarPresenter
|
|
207
|
+
|
|
208
|
+
fun init(activity: Activity) {
|
|
209
|
+
instance = StatusBarPresenter(activity)
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["EventsRegistry","NativeEventsReceiver","CommandsObserver","UniqueIdProvider","describe","uut","mockNativeEventsReceiver","commandsObserver","mockScreenEventsRegistry","beforeEach","it","subscription","cb","jest","fn","registerAppLaunchedListener","mockReturnValueOnce","result","expect","toBe","toHaveBeenCalledTimes","toHaveBeenCalledWith","registerComponentWillAppearListener","registerComponentDidAppearListener","registerComponentDidDisappearListener","registerCommandCompletedListener","registerBottomTabSelectedListener","registerNavigationButtonPressedListener","registerModalDismissedListener","registerModalAttemptedToDismissListener","registerSearchBarUpdatedListener","registerSearchBarCancelPressedListener","registerPreviewCompletedListener","registerCommandListener","toBeDefined","notify","x","remove","not","toHaveBeenCalled","bindComponent","toEqual","registerComponentListener","registerScreenPoppedListener"],"sourceRoot":"../../../src","sources":["events/EventsRegistry.test.tsx"],"mappings":";;AAAA,SAASA,cAAc,QAAQ,qBAAkB;AACjD,SAASC,oBAAoB,QAAQ,0CAAuC;AAC5E,SAASC,gBAAgB,QAAQ,uBAAoB;AACrD,SAASC,gBAAgB,QAAQ,iCAA8B;AAI/DC,QAAQ,CAAC,gBAAgB,EAAE,MAAM;EAC/B,IAAIC,GAAmB;EACvB,MAAMC,wBAAwB,GAAG,IAAIL,oBAAoB,CAAC,CAAC;EAC3D,IAAIM,gBAAkC;EACtC,MAAMC,wBAAwB,GAAG,CAAC,CAAQ;EAE1CC,UAAU,CAAC,MAAM;IACfF,gBAAgB,GAAG,IAAIL,gBAAgB,CAAC,IAAIC,gBAAgB,CAAC,CAAC,CAAC;IAC/DE,GAAG,GAAG,IAAIL,cAAc,CAACM,wBAAwB,EAAEC,gBAAgB,EAAEC,wBAAwB,CAAC;EAChG,CAAC,CAAC;EAEFE,EAAE,CAAC,2BAA2B,EAAE,MAAM;IACpC,MAAMC,YAAY,GAAG,CAAC,CAAC;IACvB,MAAMC,EAAE,GAAGC,IAAI,CAACC,EAAE,CAAC,CAAC;
|
|
1
|
+
{"version":3,"names":["EventsRegistry","NativeEventsReceiver","CommandsObserver","UniqueIdProvider","describe","uut","mockNativeEventsReceiver","commandsObserver","mockScreenEventsRegistry","beforeEach","it","subscription","cb","jest","fn","registerAppLaunchedListener","mockReturnValueOnce","result","expect","toBe","toHaveBeenCalledTimes","toHaveBeenCalledWith","registerComponentWillAppearListener","registerComponentDidAppearListener","registerComponentDidDisappearListener","registerCommandCompletedListener","registerBottomTabSelectedListener","registerNavigationButtonPressedListener","registerModalDismissedListener","registerModalAttemptedToDismissListener","registerSearchBarUpdatedListener","registerSearchBarCancelPressedListener","registerPreviewCompletedListener","registerCommandListener","toBeDefined","notify","x","remove","not","toHaveBeenCalled","bindComponent","toEqual","registerComponentListener","registerScreenPoppedListener"],"sourceRoot":"../../../src","sources":["events/EventsRegistry.test.tsx"],"mappings":"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","ignoreList":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-navigation",
|
|
3
|
-
"version": "8.8.
|
|
3
|
+
"version": "8.8.2",
|
|
4
4
|
"description": "React Native Navigation - truly native navigation for iOS and Android",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"nativePackage": true,
|
|
@@ -82,7 +82,7 @@
|
|
|
82
82
|
},
|
|
83
83
|
"dependencies": {
|
|
84
84
|
"hoist-non-react-statics": "3.3.2",
|
|
85
|
-
"lodash": "4.
|
|
85
|
+
"lodash": "4.18.1",
|
|
86
86
|
"prop-types": "15.x.x",
|
|
87
87
|
"react-lifecycles-compat": "^3.0.4",
|
|
88
88
|
"tslib": "1.9.3"
|
|
@@ -19,9 +19,9 @@ describe('EventsRegistry', () => {
|
|
|
19
19
|
it('exposes appLaunched event', () => {
|
|
20
20
|
const subscription = {};
|
|
21
21
|
const cb = jest.fn();
|
|
22
|
-
(
|
|
23
|
-
|
|
24
|
-
).mockReturnValueOnce(subscription);
|
|
22
|
+
(mockNativeEventsReceiver.registerAppLaunchedListener as jest.MockedFunction<
|
|
23
|
+
any
|
|
24
|
+
>).mockReturnValueOnce(subscription);
|
|
25
25
|
|
|
26
26
|
const result = uut.registerAppLaunchedListener(cb);
|
|
27
27
|
|