dynamic_layouts 0.6.0
dynamic_layouts: ^0.6.0 copied to clipboard
A lightweight, dependency-free Flutter package for adaptive UI rendering across mobile, tablet, and desktop screens.
dynamic_layouts #
[Dynamic Layouts Hero]
A lightweight, dependency-free Flutter package for building fluid, heavily responsive, adaptive UI rendering across mobile, tablet, and desktop screens natively.
Built on a modern, strictly reactive InheritedWidget architecture (AdaptiveScope), it efficiently responds to window resizing, layout transitions, safe-area, and orientation constraints natively.
📱 Adaptive Demos #
Experience how the package handles layout shifts from mobile to desktop seamlessly.
| Mobile Experience | Tablet & Desktop Experience |
|---|---|
| [Mobile Demo] | [Desktop Demo] |
| Bottom Navigation & List Layout | Navigation Rail & Grid Layout |
⚡ Setup & Architecture #
1. Initialize AdaptiveScope #
Inject AdaptiveScope at the application root passing a continuous ScreenConfig.watch(context).
Important
This creates a unified configuration reacting to MediaQuery bounds across the entire Flutter ecosystem natively.
import 'package:dynamic_layouts/dynamic_layouts.dart';
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return AdaptiveScope(
config: ScreenConfig.watch(
context,
designWidth: 375, // Your figma/design base width
designHeight: 812 // Your figma/design base height
),
// NEW: Clamping max width for ultra-wide screens
maxContentWidth: 1000,
child: MaterialApp(
builder: (context, child) => AdaptiveDebugOverlay(child: child!),
home: HomeScreen(),
),
);
}
}
2. Contextual Dimensional Scaling #
Safely extract responsive bounds tailored downwards into the tree. Your fonts, padding, and alignments automatically morph based on constraints.
Container(
// Scales 200 physical pixels natively relative to current bounding constraints
width: context.w(200),
height: context.h(100),
padding: EdgeInsets.all(context.w(16)),
child: Text(
'Responsive Font',
style: TextStyle(fontSize: context.sp(16)), // Text scales independently
),
)
Tip
Global static .w, .h, .sp variables extended on num are preserved for backward compatibility if you run ScreenConfig.init() strictly.
3. Scaling Basis #
Choose how your dimensions scale. By default, it uses shortestSide (similar to flutter_screenutil), but you can explicitly scale by width or height for specialized designs.
AdaptiveScope(
config: ScreenConfig.watch(
context,
defaultScaleBasis: ScaleBasis.width // Scale everything purely by width
),
child: MyApp(),
)
4. Fluid Scaling (No Breakpoint Jumps) #
If you prefer smooth, linear scaling instead of stepping through breakpoints, use the .fluid() extension. It smoothly interpolates a value based on the current screen width.
Text(
'Fluid Text',
style: TextStyle(
// Scales smoothly from 16px to 32px as screen width increases
fontSize: context.fluid(16, 32),
),
)
🛠️ Feature & UI Components Matrix #
AdaptiveValue #
Avoid if/else constraint logic inside builders. Use AdaptiveValue to conditionally map configurations directly.
// Auto-resolves based on current screen boundary.
final paddingLimit = const AdaptiveValue<double>(
mobile: 16.0,
tablet: 32.0,
desktop: 64.0,
).resolve(context);
AdaptiveLayout #
Return entirely distinct widget blueprints depending on the bounds. Supports native fallback. Use AnimatedAdaptiveLayout for smooth cross-fades when crossing breakpoints.
AdaptiveGrid #
Automagically scale grid layout matrices.
- Breakpoint-driven: Provide a responsive
crossAxisCountresolving automatically viaAdaptiveValue. - Auto-calculated: Provide a
maxColumnWidthto let the grid calculate the columns based on available space.
AdaptiveGrid(
itemCount: 20,
maxColumnWidth: 150, // Auto-column calculation!
itemBuilder: (context, index) => Card(child: Text('Item $index')),
)
AnimatedAdaptiveLayout #
A drop-in replacement for AdaptiveLayout that provides smooth cross-fades when crossing breakpoints.
AnimatedAdaptiveLayout(
duration: Duration(milliseconds: 500),
switchInCurve: Curves.easeInOut,
mobile: MobileView(),
tablet: TabletView(),
desktop: DesktopView(),
)
AdaptiveCollectionView #
Dynamically shift an axis iteration rendering natively as a ListView on tight mobile bounds, but elevating to a GridView seamlessly on tablets/desktops.
AdaptiveSliverGrid #
A sliver equivalent of AdaptiveGrid. Perfect for complex scrolling layouts inside a CustomScrollView. Automatically handles columns via crossAxisCount or maxColumnWidth.
CustomScrollView(
slivers: [
AdaptiveSliverGrid(
itemCount: 20,
maxColumnWidth: 200, // Scales nicely across any device
itemBuilder: (context, index) => Card(child: Text('Item $index')),
),
],
)
AdaptiveWrap #
Flipping between vertical Columns and horizontal Rows seamlessly based on a specified breakpoint target.
AdaptiveMasterDetail #
A robust two-pane layout system.
- Mobile: Stacks views and handles stateful layered navigation (drilling down).
- Tablet/Desktop: Splits the screen side-by-side without needing a custom router.
Adaptive Forms Suite #
A collection of widgets specifically designed to make data-entry responsive and native-feeling.
AdaptiveFormRow: Stacks form fields vertically on mobile, but spreads them laterally into responsive grid alignments on desktops.AdaptiveTextField: Automatically adjusts its internalInputDecorationto be spacious on mobile (large touch targets) and compact on desktop (isDense = true).AdaptiveFormSubmit: A button wrapper that spansdouble.infinitywidth on mobile, but gracefully shrinks and aligns to the trailing edge on desktop.
AdaptiveFormRow(
label: Text('Email Address'),
input: AdaptiveTextField.form( // Automatically scales density!
decoration: InputDecoration(hintText: 'user@example.com'),
),
),
AdaptiveFormSubmit(
child: FilledButton(onPressed: () {}, child: Text('Submit')),
)
AdaptiveNavigationScaffold #
An intelligent Scaffold that renders a native BottomNavigationBar on smaller screens, instantly snapping into a NavigationRail on Desktop limits.
AdaptiveDrawerScaffold #
A Scaffold designed for complex desktop apps that use a sidebar.
- Mobile: Acts as a standard modal
Drawerhidden behind a hamburger menu. - Tablet/Desktop: The drawer is permanently "docked" as a fixed side-pane next to your main content.
AdaptiveDrawerScaffold(
drawer: CustomSidebarWidget(),
appBar: AppBar(title: Text('Dashboard')),
body: MainContentWidget(),
)
⚙️ Breakpoint Architectures #
Built-in tailored presets corresponding to industry tracking metrics:
BreakpointConfig.material3();
BreakpointConfig.bootstrap();
BreakpointConfig.tailwind();
License #
MIT — see LICENSE