Repository navigation
Description
Use case
When running a Flutter app on large-screen devices (tablets, foldables, desktops), only one page is displayed at a time, leaving most of the screen unused. This is a significant gap compared to native platforms:
Android provides SlidingPaneLayout for master-detail two-pane UIs
iOS provides UISplitViewController
Web has CSS multi-column / grid layouts
Common apps like email clients, settings, file managers, and note-taking apps universally use a master-detail split layout on large screens. Flutter developers currently have no built-in way to achieve this that transparently works with existing Navigator/Router APIs.
To achieve a split view today, developers must write a significant amount of application code: manually detecting screen size with MediaQuery, conditionally composing Row/Column layouts, duplicating navigation logic for each screen, and managing state synchronization between panes. This adaptation must be repeated for every page in the app, and it breaks standard Navigator/Router semantics (back button, route transitions, deep linking). The result is high development cost, fragile code, and inconsistent behavior across platforms.
Proposal
Existing Alternatives and Their Limitations
| Solution | Type | App Adaptation Effort | Supports Router Routing? |
|---|---|---|---|
adaptive_scaffold |
Official package | High — requires redesigning layout tree and slot structure | N/A — does not involve navigation stack |
flutter_split_view (3rd-party) |
Package | Medium — requires replacing routing API | No — does not support RouterDelegate/RouterConfig/go_router |
flow_nav (3rd-party) |
Package | Medium — requires replacing routing API and custom route function mapping | Partial — large-screen implementation uses page replacement, no back navigation support |
| Our approach (dual overlay) | Framework-level change | Low — just enable the toggle and specify split mode; app code essentially unchanged | Yes — supports both Navigator and Router routing |
Expected Effect
An app that currently looks like this:
┌─────────────────────────┐
│ │
│ Single Page │
│ │
└─────────────────────────┘
Should automatically become this on wide screens, without modifying the app's navigation code:
┌───────────┬─────────────┐
│ │ │
│ Home │ Detail │
│ │ │
│ │ │
└───────────┴─────────────┘
Proof of Concept
We have completed a working proof of concept using the dual-overlay approach. The implementation supports all common Flutter routing patterns:
Supported Routing Patterns
| # | Pattern | Entry Point |
|---|---|---|
| 1 | initialRoute + onGenerateRoute |
MaterialApp |
| 2 | initialRoute + routes |
MaterialApp |
| 3 | home + onGenerateRoute |
MaterialApp |
| 4 | home + routes |
MaterialApp |
| 5 | CupertinoApp |
CupertinoApp |
| 6 | RouterDelegate + pages |
MaterialApp.router |
| 7 | RouterConfig |
MaterialApp.router |
| 8 | go_router |
MaterialApp.router |
How It Works (Overview)
- Dual overlay: Replaces the
Navigator's singleOverlaywith two side-by-sideOverlays. - Route allocation: Assigns route overlay entries to the appropriate overlay, enabling two pages to be visible simultaneously.
- Navigation interception: Intercepts push and pop operations to maintain split-view invariants (each overlay displays the expected page).
- Popup handling:
PopupRoutes are assigned to the correct overlay, with a mirror barrier placed on the opposite side to block interaction. - Dynamic split view visibility: Controls the visibility of left and right overlays to dynamically adjust whether the current page displays split view on screen orientation or size changes (landscape/portrait switch, fold/unfold), enabling seamless transitions.
- Two-layer toggle design: The split-view feature is implemented as a two-layer toggle — the first layer is an explicit opt-in by the app; when not enabled, the original behavior is fully preserved with zero intrusion; the second layer, once enabled, dynamically decides whether the current page presents split view based on screen resolution and orientation (landscape/portrait).
Demo
Configuration
Our local implementation currently reads configuration items such as split mode from a specific JSON configuration file. This is merely an implementation choice for the proof-of-concept stage. The configuration approach (file format, programmatic API, or framework integration) can be entirely adjusted according to upstream recommendations.
What remains unchanged: no need to modify the app's Navigator.push(), Navigator.pop(), context.go(), or any other navigation code.
Comparison with Existing Solutions
- vs.
adaptive_scaffold: Zero intrusion, no need to redesign the layout tree. The two have different positioning:adaptive_scaffoldis a layout slot system, while our approach is split view at the navigation stack level. - vs.
flutter_split_view: No need to replace routing API, supports declarative routing; but requires modifying Navigator internals. - vs.
flow_nav: The right pane maintains a real navigation stack (supports back navigation), no need to configure callbacks for each routing pattern; but requires modifying Navigator internals.
Implementation Approach
The proof of concept adds SplitViewNavigatorPolicy in navigator.dart, responsible for:
- Overlay entries reallocation: In
NavigatorState.build, route overlay entries are distributed to left and right overlays, enabling two pages to be visible simultaneously. - Navigation operation interception: Intercepts key push/pop operations to maintain split-view invariants, avoiding routing anomalies in multi-page scenarios.
- Popup and barrier handling: Assigns
PopupRouteto the correct overlay and places a mirror barrier on the opposite side to block interaction. - Dynamic split view visibility: Controls the visibility of left and right overlays to dynamically adjust whether the current page displays split view on screen orientation or size changes (landscape/portrait switch, fold/unfold), enabling seamless transitions.
- Forced split/no-split: Supports forcing specific pages into split view or fullscreen mode (e.g., video player forced fullscreen).
We are also open to other approaches preferred by the official team.
Questions for the Flutter Team
-
Is this a feature direction the team would consider for inclusion in the framework? Large-screen/foldable support is a stated priority, but current solutions (widget composition) require significant app changes. Would a more transparent, Navigator-level approach be welcome?
-
Does the team have existing development plans for similar functionality? If related work is already underway, we want to avoid duplicating effort.
-
If the feature direction is acceptable, which implementation approach does the team prefer? Specifically:
- Is directly modifying
navigator.dartacceptable? - Or should it be a pure package (at the cost of not supporting Router routing)?
- Or a new widget (e.g.,
SplitViewNavigator) wrappingNavigator?
- Is directly modifying
Background
- Platform: The implementation is cross-platform, with local testing done on Android Pixel Tablet emulator
- Flutter version: Based on Flutter 3.41.9
- Proof of concept tested with real applications (not just examples)
We are sharing this proposal early to get direction from the official team, avoiding investing significant work in an upstream-quality implementation only to be rejected. We can provide more details, code, or demos as needed.
Activity
puneetkukreja98 commentedon Jul 16, 2026
@wellwell27 Thank you for the detailed proposal and the working proof of concept.
Since this proposes framework-level changes to how navigation is handled for split views, forwarding this to the framework team for review.
[-]Built-in Split View (Dual-Pane) Support for Large Screens and Foldable Devices[/-][+]Proposal: Built-in Split View (Dual-Pane) Support for Large Screens and Foldable Devices[/+]