The Android implementation provides native navigation using Views and ViewGroups (not Fragments), coordinated through a TurboModule that receives commands from JavaScript.
File: NavigationApplication.java
Abstract Application class that user's MainApplication must extend:
// MainApplication.kt - User extends NavigationApplication
class MainApplication : NavigationApplication() {
override val reactNativeHost: ReactNativeHost
get() = NavigationReactNativeHost(this) // Must use NavigationReactNativeHost
}What NavigationApplication does:
- Initializes SoLoader
- Provides
ReactGatewaysingleton for React lifecycle - Offers
registerExternalComponent()for native screens
File: NavigationActivity.java
Base Activity that user's MainActivity must extend:
// MainActivity.kt - User extends NavigationActivity
class MainActivity : NavigationActivity() {
// No getMainComponentName() needed - navigation handles root
}What NavigationActivity does:
- Creates
Navigatorwith root, modal, and overlay layouts - Manages back press via
OnBackPressedCallback - Coordinates React lifecycle with activity lifecycle
File: react/NavigationReactNativeHost.kt
Custom ReactNativeHost that integrates with navigation:
- Used instead of
DefaultReactNativeHost - Provides proper module registration for navigation
The autolink/postlink/postLinkAndroid.js script automates setup:
| Linker | What it does |
|---|---|
ApplicationLinker |
Changes MainApplication to extend NavigationApplication, uses NavigationReactNativeHost, removes SoLoader.init() |
ActivityLinker |
Changes MainActivity to extend NavigationActivity, removes getMainComponentName() |
GradleLinker |
Updates build.gradle if needed |
ApplicationLinker transformations:
class MainApplication : Application(), ReactApplication→class MainApplication : NavigationApplication()DefaultReactNativeHost(this)→NavigationReactNativeHost(this)- Removes
SoLoader.init()(NavigationApplication handles it) - Removes new architecture entry point load block
ActivityLinker transformations:
class MainActivity : ReactActivity()→class MainActivity : NavigationActivity()- Removes
getMainComponentName()override - Removes
createReactActivityDelegate()override
android/src/main/java/com/reactnativenavigation/
├── NavigationActivity.java # Main Activity entry point
├── NavigationApplication.java # Application class
├── NavigationPackage.kt # React package registration
├── react/ # React bridge layer
│ ├── NavigationTurboModule.kt # TurboModule implementation
│ ├── ReactGateway.java # React lifecycle management
│ └── events/
│ └── EventEmitter.java # Event emission to JS
├── options/ # Options parsing and factories
│ ├── LayoutFactory.java # Creates ViewControllers from layout nodes
│ └── Options.java # Options model
├── viewcontrollers/ # ViewController hierarchy
│ ├── ViewController.java # Base class
│ ├── ChildController.java # With presenter support
│ ├── ParentController.java # Container controllers
│ ├── stack/ # Stack navigation
│ ├── bottomtabs/ # Bottom tabs
│ ├── toptabs/ # Top tabs (lowercase)
│ ├── sidemenu/ # Side menu/drawer
│ ├── modal/ # Modal management
│ └── externalcomponent/ # Native component support
├── views/ # UI View implementations
├── utils/ # Utilities
└── hierarchy/ # Root layout management
┌────────────────────────────────────────────────────────────┐
│ JavaScript (TurboModule) │
└─────────────────────────┬──────────────────────────────────┘
│
┌─────────────────────────▼──────────────────────────────────┐
│ NavigationTurboModule.kt │
│ - setRoot, push, pop, showModal, dismissModal, etc. │
└─────────────────────────┬──────────────────────────────────┘
│
┌─────────────────────────▼──────────────────────────────────┐
│ Navigator (Root ViewController) │
│ - Manages root, modals, overlays │
│ - Coordinates LayoutFactory │
└──────┬──────────────┬──────────────┬──────────────┬────────┘
│ │ │ │
┌──────▼─────┐ ┌──────▼─────┐ ┌──────▼─────┐ ┌─────▼──────┐
│ModalStack │ │OverlayMgr │ │LayoutFactory│ │EventEmitter│
└────────────┘ └────────────┘ └────────────┘ └────────────┘
Abstract Application class that apps extend:
- Manages
ReactGatewaysingleton - Initializes SoLoader
- Provides
registerExternalComponent()for native screens
Main Activity containing all navigation:
- Creates
Navigatorwith three CoordinatorLayouts:rootLayout- Main navigation contentmodalsLayout- Modal stackoverlaysLayout- Overlays (highest z-order)
- Handles back press via
OnBackPressedCallback - Coordinates activity lifecycle with React
TurboModule implementation (Kotlin, ~300 lines):
@ReactMethod
fun setRoot(commandId: String, layout: ReadableMap, promise: Promise)
@ReactMethod
fun push(commandId: String, componentId: String, layout: ReadableMap, promise: Promise)
@ReactMethod
fun showModal(commandId: String, layout: ReadableMap, promise: Promise)All commands execute on UI thread via UiThread.post().
Note: Android implementation does NOT use Fragments - it's purely View-based.
ViewController (abstract)
│ - Base for all navigation controllers
│ - Manages view creation and lifecycle
│ - Handles options and back press
│
├── ChildController
│ │ - Adds Presenter support
│ │
│ ├── ComponentViewController
│ │ - Renders React components via ReactView
│ │
│ └── ExternalComponentViewController
│ - Wraps native Android views
│
└── ParentController (extends ChildController)
- Container for child controllers
│
├── StackController
│ - Push/pop navigation
│ - Uses IdStack<ViewController>
│
├── BottomTabsController
│ - UITabBarController equivalent
│ - Uses AHBottomNavigation
│
├── TopTabsController
│ - Horizontal ViewPager tabs
│
├── SideMenuController
│ - DrawerLayout-based drawer
│
└── Navigator
- Root controller
- Manages modals and overlays
File: viewcontrollers/viewcontroller/ViewController.java (~500 lines)
Abstract base for all navigation controllers:
public abstract class ViewController<T extends ViewGroup> {
protected abstract T createView(); // Subclasses create views
public void onViewWillAppear() { }
public void onViewDidAppear() { }
public void onViewDisappear() { }
public void mergeOptions(Options options) { }
public void applyOptions(Options options) { }
public boolean handleBack(CommandListener listener) { }
public void destroy() { }
}File: viewcontrollers/navigator/Navigator.java
Root ViewController managing:
- Root content hierarchy
- Modal stack (
ModalStack) - Overlay manager (
OverlayManager) - Component lookup by ID
File: options/LayoutFactory.java
Factory creating ViewControllers from LayoutNode. Owned by NavigationTurboModule and used to build the view controller hierarchy when commands are received from JavaScript.
public ViewController create(LayoutNode node) {
switch (node.type) {
case Component: return createComponent(node);
case Stack: return createStack(node);
case BottomTabs: return createBottomTabs(node);
case SideMenuRoot: return createSideMenuRoot(node);
case SideMenuCenter: return createSideMenuContent(node);
case SideMenuLeft: return createSideMenuLeft(node);
case SideMenuRight: return createSideMenuRight(node);
case TopTabs: return createTopTabs(node);
// Note: SplitView is iOS-only, not implemented on Android
}
}Files: viewcontrollers/stack/
- View:
StackLayout(CoordinatorLayout with TopBar) - Internal stack:
IdStack<ViewController<?>> - Components:
TopBarController,StackAnimator,StackPresenter,FabPresenter
Operations:
push(viewController, listener)pop(options, listener)popTo(target, options, listener)popToRoot(options, listener)setRoot(children, listener)
Files: viewcontrollers/bottomtabs/
- View:
BottomTabsLayout(CoordinatorLayout with BottomTabs) - Uses
AHBottomNavigationlibrary - Components:
BottomTabsPresenter,BottomTabPresenter,BottomTabsAnimator
Attachment Modes:
TogetherAttacher- Load all tabs immediatelyOnSwitchToTabAttacher- Lazy load on selectionAfterInitialTabAttacher- Load initial + others in background
Files: viewcontrollers/sidemenu/
- View:
SideMenuRoot(DrawerLayout-based) - Children: Center, Left, Right controllers
SideMenuPresenterfor styling
Files: viewcontrollers/toptabs/
- View:
TopTabsViewPager(ViewPager-based) TopTabsLayoutCreatorfor view creation
Files: viewcontrollers/modal/
Not a ViewController - manages modal presentation:
ModalPresenter- Show/dismiss with animationsModalAnimator(Kotlin) - Animation handling- Stack of modals with lifecycle management
File: viewcontrollers/overlay/OverlayManager.kt
Registry of active overlays:
- Show/dismiss by component ID
- Configuration change handling
- Host pause/resume lifecycle
Manages React component lifecycle:
- Creates
ComponentLayoutview - Initializes
ReactViewwith ReactSurface - Emits lifecycle events to JS
- Handles scroll events and status bar
File: react/ReactView.java
Extends FrameLayout, wraps ReactSurface:
start()- Attach surface to React instancedestroy()- Clean up React surfacesendComponentWillStart()- Emit event to JSisReady()- Check surface attachment
File: react/events/EventEmitter.java
Events sent to JavaScript:
| Event | Description |
|---|---|
RNN.AppLaunched |
App initialization complete |
RNN.ComponentDidAppear |
Component visible |
RNN.ComponentWillAppear |
About to become visible |
RNN.ComponentDidDisappear |
Component hidden |
RNN.NavigationButtonPressed |
TopBar button tapped |
RNN.BottomTabSelected |
Tab selection changed |
RNN.BottomTabPressed |
Tab pressed (even if selected) |
RNN.ModalDismissed |
Modal was dismissed |
RNN.ScreenPopped |
Screen removed from stack |
RNN.CommandCompleted |
Navigation command finished |
File: options/Options.java
public class Options {
public TopBarOptions topBar;
public TopTabsOptions topTabs;
public BottomTabsOptions bottomTabsOptions;
public BottomTabOptions bottomTabOptions;
public OverlayOptions overlayOptions;
public FabOptions fabOptions;
public AnimationsOptions animations;
public SideMenuRootOptions sideMenuRootOptions;
public ModalOptions modal;
public StatusBarOptions statusBar;
public NavigationBarOptions navigationBar;
public LayoutOptions layout;
public HardwareBackButtonOptions hardwareBack;
}- Parse: JSON from JS → Options object via JSONParser
- Merge: Default → Screen → Component options
- Apply: Presenter applies to views
Each ViewController has a Presenter:
| ViewController | Presenter |
|---|---|
| StackController | StackPresenter |
| BottomTabsController | BottomTabsPresenter + BottomTabPresenter |
| ComponentViewController | ComponentPresenter |
| SideMenuController | SideMenuPresenter |
| Navigator | RootPresenter |
File: viewcontrollers/viewcontroller/Presenter.java
Handles:
- Orientation changes
- Status bar styling
- Navigation bar styling
- Layout parameters
StackAnimator.kt- Push, pop, setRoot animationsModalAnimator.kt- Modal show/dismissBottomTabsAnimator.kt- Tab transitionsTopBarAppearanceAnimator.kt- Top bar changes
Via TransitionAnimatorCreator.kt:
- Position, scale, rotation animations
- Color transitions
- Corner radius animations
- Shared element support
onCreate() // Create Navigator, initialize React
onPostCreate() // Set content layout
onResume() // React host resume, event emitter setup
onPause() // React host pause
onDestroy() // Clean up Navigator
onConfigurationChanged() // Handle orientation, locale
onNewIntent() // Process deep links
onActivityResult() // Handle permissionsView creation
↓
onViewWillAppear() // Register with registry
↓
onViewDidAppear() // Emit event to JS
↓
[visible]
↓
onViewWillDisappear()
↓
onViewDisappear() // Unregister from registry
↓
destroy() // Complete cleanup
All paths relative to android/src/main/java/com/reactnativenavigation/:
| File | Path | Purpose |
|---|---|---|
| NavigationActivity.java | . |
Main Activity |
| NavigationApplication.java | . |
Application class |
| NavigationTurboModule.kt | react/ |
JS bridge |
| Navigator.java | viewcontrollers/navigator/ |
Root controller |
| ViewController.java | viewcontrollers/viewcontroller/ |
Base class |
| StackController.java | viewcontrollers/stack/ |
Stack navigation |
| BottomTabsController.java | viewcontrollers/bottomtabs/ |
Tab navigation |
| LayoutFactory.java | options/ |
Controller factory |
| Options.java | options/ |
Options model |
| Presenter.java | viewcontrollers/viewcontroller/ |
Base presenter |
| EventEmitter.java | react/events/ |
JS events |
| ReactView.java | react/ |
React component wrapper |
| StackAnimator.kt | viewcontrollers/stack/ |
Stack animations |
| ModalStack.java | viewcontrollers/modal/ |
Modal management |