Skip to content

Commit b7281dd

Browse files
committed
feat(android): prevent native tab selection in TabsContainer
When a tab has preventNativeSelection enabled, block native user taps from selecting it. Returns false from OnItemSelectedListener to prevent BottomNavigationView from updating its visual selection state, and emits onTabSelectionPrevented event to JS via TabsContainerDelegate chain.
1 parent 8ebd657 commit b7281dd

4 files changed

Lines changed: 28 additions & 0 deletions

File tree

android/src/main/java/com/swmansion/rnscreens/gamma/tabs/container/TabsContainer.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,12 @@ internal class TabsContainer(
361361

362362
val isRepeated = nextSelectedFragment === currSelectedFragment
363363

364+
// If this is user action we test whether it should be prevented before we progress the state.
365+
if (!isRepeated && !isInExternalOperationContext && nextSelectedFragment.isPreventNativeSelectionEnabled) {
366+
delegate.onNavStateUpdatePrevented(navState, nextSelectedFragment.requireScreenKey)
367+
return false
368+
}
369+
364370
val stateChanged = updateSelectedFragment(nextSelectedFragment)
365371

366372
val hasTriggeredSpecialEffect =

android/src/main/java/com/swmansion/rnscreens/gamma/tabs/container/TabsContainerDelegate.kt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,17 @@ internal interface TabsContainerDelegate {
3232
rejectedNavState: TabsNavState,
3333
reason: TabsNavStateUpdateRejectionReason,
3434
)
35+
36+
/**
37+
* Called when a native user action (tap) attempts to select a tab that has
38+
* [com.swmansion.rnscreens.gamma.tabs.screen.TabsScreen.preventNativeSelection] enabled.
39+
* The navigation state remains unchanged.
40+
*
41+
* @param currentNavState The currently active navigation state that was kept.
42+
* @param preventedScreenKey The screen key of the tab whose selection was prevented.
43+
*/
44+
fun onNavStateUpdatePrevented(
45+
currentNavState: TabsNavState,
46+
preventedScreenKey: String
47+
)
3548
}

android/src/main/java/com/swmansion/rnscreens/gamma/tabs/host/TabsHost.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,13 @@ class TabsHost(
182182
)
183183
}
184184

185+
override fun onNavStateUpdatePrevented(
186+
currentNavState: TabsNavState,
187+
preventedScreenKey: String
188+
) {
189+
eventEmitter.emitOnTabSelectionPreventedEvent(currentNavState, preventedScreenKey)
190+
}
191+
185192
override fun didMountItems(uiManager: UIManager) {
186193
container.performContainerUpdateIfNeeded()
187194
}

android/src/main/java/com/swmansion/rnscreens/gamma/tabs/screen/TabsScreenFragment.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ class TabsScreenFragment(
1111
internal val tabsScreen: TabsScreen,
1212
) : Fragment() {
1313
internal val requireScreenKey: String by tabsScreen::requireScreenKey
14+
internal val isPreventNativeSelectionEnabled: Boolean by tabsScreen::preventNativeSelection
1415

1516
override fun onCreateView(
1617
inflater: LayoutInflater,
@@ -44,4 +45,5 @@ class TabsScreenFragment(
4445
// Handle theme change through RN's Appearance.setColorScheme
4546
tabsScreen.onFragmentConfigurationChange(this, newConfig)
4647
}
48+
4749
}

0 commit comments

Comments
 (0)