flutter_screenutil_plus 1.3.1 copy "flutter_screenutil_plus: ^1.3.1" to clipboard
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

flutter_screenutil_plus #

Flutter Package Pub Points License

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 changes
  • RebuildFactors.orientation - Rebuild when orientation changes
  • RebuildFactors.sizeAndViewInsets - Rebuild when view insets change
  • RebuildFactors.change - Rebuild on any MediaQuery change
  • RebuildFactors.always - Always rebuild
  • RebuildFactors.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 width
  • FontSizeResolvers.height - Scale based on screen height
  • FontSizeResolvers.radius - Scale based on the smaller of width/height
  • FontSizeResolvers.diameter - Scale based on the larger of width/height
  • FontSizeResolvers.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 SU mixin
  • responsiveWidgets does 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 #

  1. Set design size once: Initialize ScreenUtilPlusInit at the root of your app
  2. Use .r for squares: Use .r extension when you want perfect squares
  3. Use breakpoints for major layout changes: Use ResponsiveBuilder for different layouts
  4. Use size classes for adaptive UI: Use SizeClassBuilder for SwiftUI-like adaptive layouts
  5. Combine with responsive widgets: Use AdaptiveContainer for breakpoint-aware properties
  6. 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 #


Made with โค๏ธ by Muhammad Kamel

4
likes
160
points
744
downloads

Publisher

unverified uploader

Weekly Downloads

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.

Repository (GitHub)
View/report issues

Documentation

API reference

License

MIT (license)

Dependencies

equatable, flutter

More

Packages that depend on flutter_screenutil_plus