flutter_screenutil_plus 1.3.1
flutter_screenutil_plus: ^1.3.1 copied to clipboard
A powerful Flutter plugin for adaptive screen and font scaling with CSS-like breakpoints and SwiftUI-style size classes. Includes responsive scaling and breakpoint-aware widgets.
flutter_screenutil_plus #
A powerful Flutter plugin for adapting screen and font size with CSS-like breakpoints and SwiftUI-like size classes. Let your UI display a reasonable layout on different screen sizes!
โจ Features #
- ๐ฑ Responsive Scaling: Automatic scaling of width, height, font size, and more
- ๐ฏ CSS-like Breakpoints: Media query-style breakpoints (Bootstrap, Tailwind, Material Design)
- ๐ SwiftUI-like Size Classes: Compact/Regular size classes for adaptive layouts
- ๐จ Adaptive Widgets: Breakpoint-aware containers, text, and builders
- ๐ Performance Optimized: Intelligent rebuild detection with Equatable
- ๐ญ Responsive Theme: Automatic text style scaling in themes
- ๐ฆ Zero Configuration: Works out of the box with sensible defaults
- ๐งช Well Tested: 98.3% code coverage with 500+ tests
๐ฆ Installation #
Add this to your package's pubspec.yaml file:
dependencies:
flutter_screenutil_plus: ^1.2.0
Then run:
flutter pub get
๐ Quick Start #
1. Initialize the Library #
Wrap your app with ScreenUtilPlusInit:
import 'package:flutter_screenutil_plus/flutter_screenutil_plus.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ScreenUtilPlusInit(
designSize: const Size(360, 690),
minTextAdapt: true,
splitScreenMode: true,
builder: (context, child) {
return MaterialApp(
title: 'Flutter ScreenUtil Plus',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: child,
);
},
child: const HomePage(),
);
}
}
2. Use Responsive Extensions #
Container(
width: 100.w, // Responsive width
height: 50.h, // Responsive height
padding: EdgeInsets.all(16.r), // Responsive padding
child: Text(
'Hello World',
style: TextStyle(fontSize: 16.sp), // Responsive font
),
)
๐ Core Features #
Responsive Extensions #
The package provides extension methods for easy responsive sizing:
// Width and Height
100.w // Adapt to screen width
100.h // Adapt to screen height
100.r // Adapt to smaller of width/height (radius)
100.dm // Adapt to larger of width/height (diameter)
100.dg // Adapt based on diagonal calculation
// Font Size
16.sp // Responsive font size
16.spMin // min(16, 16.sp) - prevents font from being too large
16.spMax // max(16, 16.sp) - ensures minimum font size
// Screen Dimensions
1.sw // Screen width
1.sh // Screen height
// Spacing Helpers
20.verticalSpace // SizedBox(height: 20 * scaleHeight)
20.horizontalSpace // SizedBox(width: 20 * scaleWidth)
Responsive Widgets #
Pre-built widgets that automatically apply scaling:
// Responsive Container
RContainer(
width: 100,
height: 50,
padding: EdgeInsets.all(8),
child: Text('Responsive'),
)
// Responsive Padding
RPadding(
padding: EdgeInsets.all(16),
child: Text('Padded'),
)
// Responsive SizedBox
RSizedBox(width: 100, height: 50)
// Responsive Text (auto-scales fontSize)
RText('Hello', style: TextStyle(fontSize: 16))
๐ฏ CSS-like Breakpoints #
Create responsive designs similar to CSS media queries.
Using Breakpoints #
// Get current breakpoint
final breakpoint = context.breakpoint; // xs, sm, md, lg, xl, xxl
// Check breakpoints
if (context.isAtLeast(Breakpoint.md)) {
// Tablet and larger
}
if (context.isLessThan(Breakpoint.lg)) {
// Smaller than desktop
}
if (context.isBetween(Breakpoint.sm, Breakpoint.lg)) {
// Between small and large
}
Predefined Breakpoint Sets #
// Bootstrap 5 (default)
Breakpoints.bootstrap // xs: 0, sm: 576, md: 768, lg: 992, xl: 1200, xxl: 1400
// Tailwind CSS
Breakpoints.tailwind // sm: 640, md: 768, lg: 1024, xl: 1280, xxl: 1536
// Material Design
Breakpoints.material // sm: 600, md: 960, lg: 1280, xl: 1920, xxl: 2560
// Mobile-first
Breakpoints.mobileFirst // sm: 480, md: 768, lg: 1024, xl: 1440, xxl: 1920
// Custom breakpoints
const customBreakpoints = Breakpoints(
xs: 0,
sm: 480,
md: 768,
lg: 1024,
xl: 1440,
);
ResponsiveBuilder #
Build different layouts for different breakpoints:
ResponsiveBuilder(
xs: (context) => MobileLayout(),
sm: (context) => MobileLandscapeLayout(),
md: (context) => TabletLayout(),
lg: (context) => DesktopLayout(),
xl: (context) => LargeDesktopLayout(),
)
AdaptiveContainer #
Container that adapts properties based on breakpoints:
AdaptiveContainer(
width: {
Breakpoint.xs: 100,
Breakpoint.md: 200,
Breakpoint.lg: 300,
},
padding: {
Breakpoint.xs: EdgeInsets.all(8),
Breakpoint.md: EdgeInsets.all(16),
Breakpoint.lg: EdgeInsets.all(24),
},
child: Text('Adaptive Container'),
)
// Or use SimpleAdaptiveContainer for easier syntax
SimpleAdaptiveContainer(
widthXs: 100,
widthMd: 200,
widthLg: 300,
paddingXs: 8,
paddingMd: 16,
child: Text('Simple Adaptive'),
)
Responsive Queries #
Get values based on breakpoints:
final query = ResponsiveQuery.of(context);
// Get value based on current breakpoint
final padding = query.value(
xs: 8.0,
sm: 12.0,
md: 16.0,
lg: 24.0,
);
// Or use AdaptiveValues for responsive sizing
final adaptive = AdaptiveValues.of(context);
final width = adaptive.width(xs: 50, sm: 100, md: 150, lg: 200);
final fontSize = adaptive.fontSize(xs: 12, sm: 14, md: 16, lg: 18);
๐ SwiftUI-like Size Classes #
Create adaptive layouts using size classes (similar to SwiftUI).
Using Size Classes #
// Get size classes
final sizeClasses = context.sizeClasses;
// Check size classes
if (sizeClasses.isRegular) {
// Regular size (e.g., iPad)
}
if (sizeClasses.isCompact) {
// Compact size (e.g., iPhone in portrait)
}
// Check individual dimensions
if (sizeClasses.isRegularHorizontal) {
// Wide screen
}
if (sizeClasses.isCompactVertical) {
// Short screen
}
SizeClassBuilder #
Build different layouts based on size classes:
SizeClassBuilder(
compact: (context) => CompactLayout(),
regular: (context) => RegularLayout(),
)
// Or with horizontal/vertical size classes
SizeClassBuilder(
horizontal: (context, horizontal) {
return horizontal == SizeClass.regular
? WideLayout()
: NarrowLayout();
},
vertical: (context, vertical) {
return vertical == SizeClass.regular
? TallLayout()
: ShortLayout();
},
)
// Or with full size class information
SizeClassBuilder(
builder: (context, sizeClasses) {
return Text(
'H: ${sizeClasses.horizontal}, V: ${sizeClasses.vertical}',
);
},
)
Custom Threshold #
SizeClassBuilder(
threshold: 600, // Custom threshold (default: 600)
compact: (context) => CompactLayout(),
regular: (context) => RegularLayout(),
)
๐จ Adaptive Text Styles #
Create text styles that adapt based on breakpoints:
// Using context extension
final style = context.adaptiveTextStyle(
xs: TextStyle(fontSize: 12, color: Colors.black),
md: TextStyle(fontSize: 16, color: Colors.blue),
lg: TextStyle(fontSize: 20, color: Colors.green),
);
// Using AdaptiveText widget
AdaptiveText(
'Adaptive Text',
xs: TextStyle(fontSize: 12),
md: TextStyle(fontSize: 16),
lg: TextStyle(fontSize: 20),
)
// Using TextStyle extensions
TextStyle(fontSize: 16)
.r // Makes fontSize responsive
.withLineHeight(1.5) // Sets line height
.withAutoLineHeight() // Auto-calculates line height
๐ง Advanced Usage #
Conditional Rendering #
ConditionalBuilder(
condition: (context) => context.isAtLeast(Breakpoint.md),
builder: (context) => DesktopLayout(),
fallback: (context) => MobileLayout(),
)
Responsive Theme #
Automatically scale all text styles in your theme:
ScreenUtilPlusInit(
designSize: const Size(360, 690),
builder: (context, child) {
return MaterialApp(
theme: ResponsiveTheme.fromTheme(
ThemeData(
primarySwatch: Colors.blue,
textTheme: TextTheme(
headlineLarge: TextStyle(fontSize: 24),
bodyLarge: TextStyle(fontSize: 16),
),
),
),
home: child,
);
},
child: HomePage(),
)
Properties #
| Property | Type | Default Value | Description |
|---|---|---|---|
| designSize | Size | Size(360,690) | The size of the device screen in the design draft, in dp |
| builder | Function | null | Return widget that uses the library in a property (ex: MaterialApp's theme) |
| child | Widget | null | A part of builder that its dependencies/properties don't use the library |
| rebuildFactor | RebuildFactor | RebuildFactors.size | Function that takes old and new screen metrics and returns whether to rebuild or not when changes occur. See RebuildFactors |
| splitScreenMode | bool | false | Support for split screen mode |
| minTextAdapt | bool | false | Whether to adapt the text according to the minimum of width and height |
| ensureScreenSize | bool | false | Whether to wait for screen size to be initialized before building (useful for web/desktop) |
| fontSizeResolver | FontSizeResolver | FontSizeResolvers.width | Function that specifies how font size should be adapted. See FontSizeResolvers |
| responsiveWidgets | Iterable | null | List/Set of widget names that should be included in rebuilding tree. (See How flutter_screenutil_plus marks a widget needs build) |
| enableScaleWH | Function | null | Function to enable/disable scaling of width and height |
| enableScaleText | Function | null | Function to enable/disable scaling of text |
Note : You must either provide builder, child or both.
Rebuild Factors #
The rebuildFactor parameter controls when the widget tree should rebuild based on MediaQuery changes. Available options:
RebuildFactors.size(default) - Rebuild when screen size changesRebuildFactors.orientation- Rebuild when orientation changesRebuildFactors.sizeAndViewInsets- Rebuild when view insets changeRebuildFactors.change- Rebuild on any MediaQuery changeRebuildFactors.always- Always rebuildRebuildFactors.none- Never rebuild automatically
You can also provide a custom function:
rebuildFactor: (oldData, newData) => oldData.size != newData.size
Font Size Resolvers #
The fontSizeResolver parameter controls how font sizes are calculated. Available options:
FontSizeResolvers.width(default) - Scale based on screen widthFontSizeResolvers.height- Scale based on screen heightFontSizeResolvers.radius- Scale based on the smaller of width/heightFontSizeResolvers.diameter- Scale based on the larger of width/heightFontSizeResolvers.diagonal- Scale based on diagonal calculation
You can also provide a custom function:
fontSizeResolver: (fontSize, instance) => instance.setWidth(fontSize * 0.9)
Rebuild List #
Starting from version 1.0.0, ScreenUtilInit won't rebuild the whole widget tree, instead it will mark widget needs build only if:
- Widget is not a flutter widget (widgets are available in Flutter Docs)
- Widget does not start with underscore (
_) - Widget does not declare
SUmixin responsiveWidgetsdoes not contains widget name
If you have a widget that uses the library and doesn't meet these options you can either add SU mixin or add widget name in responsiveWidgets list.
Using the SU Mixin
To mark a custom widget for automatic rebuilding, use the SU mixin:
import 'package:flutter_screenutil_plus/flutter_screenutil_plus.dart';
class MyCustomWidget extends StatelessWidget with SU {
@override
Widget build(BuildContext context) {
return Container(
width: 100.w,
height: 50.h,
child: Text('Responsive', style: TextStyle(fontSize: 16.sp)),
);
}
}
Enable or Disable Scaling #
Widget build(BuildContext context) {
return ScreenUtilPlusInit(
enableScaleWH: () => false, // Disable width/height scaling
enableScaleText: () => false, // Disable text scaling
//...
);
}
or
ScreenUtilPlus.enableScale(
enableWH: () => false,
enableText: () => false
);
Device Type Detection #
You can detect the device type for platform-specific UI adjustments:
final deviceType = ScreenUtilPlus().deviceType(context);
switch (deviceType) {
case DeviceType.mobile:
// Mobile-specific UI
break;
case DeviceType.tablet:
// Tablet-specific UI
break;
case DeviceType.web:
// Web-specific UI
break;
// ... other device types
}
API Reference #
Extension Methods
| Extension | Description | Example |
|---|---|---|
.w |
Adapt to screen width | 100.w |
.h |
Adapt to screen height | 100.h |
.r |
Adapt to smaller of width/height | 100.r |
.dm |
Adapt to larger of width/height | 100.dm |
.dg |
Adapt based on diagonal | 100.dg |
.sp |
Responsive font size | 16.sp |
.spMin |
Minimum font size | 12.spMin |
.spMax |
Maximum font size | 16.spMax |
.sw |
Screen width | 1.sw |
.sh |
Screen height | 1.sh |
Context Extensions
| Extension | Description | Example |
|---|---|---|
context.breakpoint |
Current breakpoint | context.breakpoint |
context.isAtLeast() |
Check if at least breakpoint | context.isAtLeast(Breakpoint.md) |
context.isLessThan() |
Check if less than breakpoint | context.isLessThan(Breakpoint.lg) |
context.isBetween() |
Check if between breakpoints | context.isBetween(Breakpoint.sm, Breakpoint.lg) |
context.sizeClasses |
Get size classes | context.sizeClasses |
context.adaptive() |
Get AdaptiveValues | context.adaptive() |
context.responsive() |
Get ResponsiveQuery | context.responsive() |
Widgets
| Widget | Description |
|---|---|
ScreenUtilPlusInit |
Initialize the library |
RContainer |
Responsive Container |
RPadding |
Responsive Padding |
RSizedBox |
Responsive SizedBox |
RText |
Responsive Text |
AdaptiveContainer |
Breakpoint-aware Container |
SimpleAdaptiveContainer |
Simplified adaptive container |
AdaptiveText |
Breakpoint-aware Text |
ResponsiveBuilder |
Builder for different breakpoints |
SizeClassBuilder |
Builder for size classes |
ConditionalBuilder |
Conditional rendering |
Performance Optimizations #
Starting from version 1.1.1, the package includes intelligent change detection using Equatable to optimize rebuilds:
- Automatic change detection: Only rebuilds registered elements when screen metrics actually change
- Value-based equality: Uses Equatable to compare screen configuration state efficiently
- Reduced unnecessary rebuilds: Prevents rebuilds when configuration remains functionally identical
This optimization is automatic and requires no code changes. The package will only trigger rebuilds when:
- Screen size changes
- Orientation changes
- Split screen mode changes
- Minimum text adaptation setting changes
- Font size resolver function changes
๐ก Best Practices #
- Set design size once: Initialize
ScreenUtilPlusInitat the root of your app - Use
.rfor squares: Use.rextension when you want perfect squares - Use breakpoints for major layout changes: Use
ResponsiveBuilderfor different layouts - Use size classes for adaptive UI: Use
SizeClassBuilderfor SwiftUI-like adaptive layouts - Combine with responsive widgets: Use
AdaptiveContainerfor breakpoint-aware properties - Test on multiple devices: Always test your responsive design on different screen sizes
๐ฏ Complete Example #
import 'package:flutter/material.dart';
import 'package:flutter_screenutil_plus/flutter_screenutil_plus.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ScreenUtilPlusInit(
designSize: const Size(360, 690),
minTextAdapt: true,
builder: (context, child) {
return MaterialApp(
title: 'Flutter ScreenUtil Plus',
theme: ResponsiveTheme.fromTheme(
ThemeData(
primarySwatch: Colors.blue,
textTheme: TextTheme(
headlineLarge: TextStyle(fontSize: 24),
bodyLarge: TextStyle(fontSize: 16),
),
),
),
home: child,
);
},
child: const HomePage(),
);
}
}
class HomePage extends StatelessWidget {
const HomePage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Flutter ScreenUtil Plus'),
),
body: ResponsiveBuilder(
xs: (context) => _MobileLayout(),
md: (context) => _TabletLayout(),
lg: (context) => _DesktopLayout(),
),
);
}
}
class _MobileLayout extends StatelessWidget {
@override
Widget build(BuildContext context) {
return SingleColumnLayout();
}
}
class _TabletLayout extends StatelessWidget {
@override
Widget build(BuildContext context) {
return TwoColumnLayout();
}
}
class _DesktopLayout extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ThreeColumnLayout();
}
}
๐ค Contributing #
Contributions are welcome! Please feel free to submit a Pull Request.
๐ License #
This project is licensed under the MIT License - see the LICENSE file for details.
๐ Acknowledgments #
- Inspired by flutter_screenutil
- Breakpoint system inspired by CSS media queries
- Size class system inspired by SwiftUI
๐ Support #
- ๐ Issues: GitHub Issues
- ๐ Documentation: Full Documentation
- ๐ง Email: mu7ammadkamel@hotmail.com
Made with โค๏ธ by Muhammad Kamel