smart_sizer 1.1.1

SDKflutter
Platformandroidioswindowslinuxmacosweb

A set of Flutterfor measuring screens and automatic responsiveness with all systems and screens..

📦 smart_sizer

A lightweight and flexible Flutter package that helps you build responsive UIs based on a fixed reference screen size. Automatically scale width, height, font size, and more for all devices.

📱📲📺 Adapt your app beautifully on mobile, tablet, and desktop.


🚀 Installation

dependencies:
  smart_sizer: ^1.1.1

Then:

flutter pub get

✅ Usage

1️⃣ Wrap your app with SizeBuilder in MyHomePage:

import 'package:flutter/material.dart';
import 'package:smart_sizer/smart_sizer.dart';

void main() {
  runApp(
      return const MyApp(),
  );
}

class MyHomePage extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return   SizeBuilder(
          baseSize: Size(360, 690),
          height: context.screenHeight,
          width: context.screenWidth,
          child: MaterialApp(
      
            debugShowCheckedModeBanner: false,
            home : MainScreen(),
          ));
  }
}

2️⃣ Use extension methods inside your widgets:

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Container(
          width: context.getWidth(60),
          height: context.getHeight(20),
          color: Colors.blue,
          child: Text(
            'Hello Ahmed',
            style: TextStyle(fontSize: context.getFontSize(16)),
          ),
        ),
      ),
    );
  }
}

More example


class LoginScreen extends StatelessWidget {
  const LoginScreen({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Padding(
        padding: EdgeInsets.all(context.getWidth(24)),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text(
              'Login',
              style: TextStyle(
                fontSize: context.getFontSize(22),
                fontWeight: FontWeight.bold,
              ),
            ),
            SizedBox(height: context.getHeight(20)),
            TextField(
              decoration: InputDecoration(
                hintText: 'Email',
                contentPadding: EdgeInsets.symmetric(
                  horizontal: context.getWidth(16),
                  vertical: context.getHeight(12),
                ),
              ),
            ),
            SizedBox(height: context.getHeight(16)),
            TextField(
              decoration: InputDecoration(
                hintText: 'Password',
                contentPadding: EdgeInsets.symmetric(
                  horizontal: context.getWidth(16),
                  vertical: context.getHeight(12),
                ),
              ),
            ),
            SizedBox(height: context.getHeight(24)),
            ElevatedButton(
              onPressed: () {},
              style: ElevatedButton.styleFrom(
                padding: EdgeInsets.symmetric(
                  vertical: context.getHeight(14),
                  horizontal: context.getWidth(40),
                ),
              ),
              child: Text(
                'Submit',
                style: TextStyle(fontSize: context.getFontSize(16)),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

3️⃣ Use DeviceUtils methods inside your widgets:



class GridExampleScreen extends StatelessWidget {
  const GridExampleScreen({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("Responsive GridView")),
      backgroundColor: AppColors.accent,
      body: Padding(
        padding: EdgeInsets.all(context.getWidth(12)),
        child: GridView.builder(
          gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
            // Use GridView to All OS and Device
            crossAxisCount: DeviceUtils.valueDecider(
              context,
              onMobile: 2,
              onTablet: 3,
              onDesktop: 4,
            ),
            crossAxisSpacing: context.getWidth(10),
            mainAxisSpacing: context.getHeight(10),
            childAspectRatio: 1, 
          ),
          itemCount: 20,
          itemBuilder: (context, index) {
            return Container(
              alignment: Alignment.center,
              decoration: BoxDecoration(
                color: Colors.blue,
                borderRadius: BorderRadius.circular(context.getMinSize(12)),
              ),
              child: Text(
                "Item ${index + 1}",
                style: TextStyle(
                  fontSize: context.getFontSize(14),
                  color: Colors.white,
                ),
              ),
            );
          },
        ),
      ),
    );
  }
}

4️⃣ Use SizeBuilder in card widgets :


/// 📄 Example screen: A responsive ListView of Cards
/// This screen demonstrates how to create a **responsive list of cards**
/// using `SizeBuilder` and `smart_sizer` utilities.
/// 
/// Features:
/// ✅ Each card adapts in height, width, and font size 🪄
/// ✅ Includes interactive tap and button actions 🎯
/// ✅ Example of using `context.getFontSize`, `context.getWidth`, and `context.getHeight`
/// 
/// Perfect for showing lists, menus, or catalog items 📋

class ResponsiveCardListScreen extends StatelessWidget {
  const ResponsiveCardListScreen({super.key});

  
  @override
  Widget build(BuildContext context) {

 final items = List.generate(12, (i) => {
      'title': 'Card title ${i + 1}',
      'subtitle': 'This is a brief description of item ${i + 1}.',
      'icon': Icons.widgets,
    });

    return Scaffold(
      appBar: AppBar(
        title: Text(
          'Responsive Cards',
          style: TextStyle(fontSize: context.getFontSize(18)),
        ),
      ),
      body: Container(

        height: context.sizeBuilder.height,
        child: SizeBuilder( baseSize: Size(250,250),
          height: context.getMinSize(250),
          width: context.getMinSize(250),
          child:  Builder(builder: (context) {
            return SizedBox(

              child: ListView.builder(

                padding: EdgeInsets.only(
                  top: context.getHeight(12),
                  bottom: context.getHeight(12),
                ),
                itemCount: items.length,

                itemBuilder: (context, index) {
                  final item = items[index];
                  return Card(

                    elevation: 4,
                    shape: RoundedRectangleBorder(
                      borderRadius: BorderRadius.circular(context.getMinSize(14)),
                    ),
                    child: InkWell(
                      onTap: () {
                  
                        ScaffoldMessenger.of(context).showSnackBar(
                          SnackBar(content: Text('Tapped ${item['title']}')),
                        );
                      },
                      borderRadius: BorderRadius.circular(context.getMinSize(14)),
                      child: SizedBox(
                        height: context.sizeBuilder.height/2 ,

                        child: Padding(
                          padding: EdgeInsets.symmetric(
                            horizontal: context.getWidth(12),
                            vertical: context.getHeight(12),
                          ),
                          child: Row(
                            children: [

                              CircleAvatar(
                                radius: context.getMinSize(28),
                                backgroundColor: Theme.of(context).colorScheme.primary.withOpacity(0.12),
                                child: Icon(
                                  item['icon'] as IconData,
                                  size: context.getFontSize(20),
                                  color: Theme.of(context).colorScheme.primary,
                                ),
                              ),

                              SizedBox(width: context.getWidth(12)),


                              Expanded(
                                child: Column(
                                  crossAxisAlignment: CrossAxisAlignment.start,
                                  children: [
                                    Text(
                                      item['title'] as String,
                                      style: TextStyle(
                                        fontSize: context.getFontSize(16),
                                        fontWeight: FontWeight.w700,
                                      ),
                                    ),
                                    SizedBox(height: context.getHeight(6)),
                                    Text(
                                      item['subtitle'] as String,
                                      style: TextStyle(
                                        fontSize:  context.getFontSize(14),
                                        color: Theme.of(context).textTheme.bodySmall?.color?.withOpacity(0.8),
                                      ),
                                      maxLines: 2,
                                      overflow: TextOverflow.ellipsis,
                                    ),
                                  ],
                                ),
                              ),

                              SizedBox(width: context.getWidth(12)),
                              ElevatedButton(
                                onPressed: () {
                                
                                  ScaffoldMessenger.of(context).showSnackBar(
                                    SnackBar(content: Text('Action for ${item['title']}')),
                                  );
                                },
                                style: ElevatedButton.styleFrom(
                                  padding: EdgeInsets.symmetric(
                                    horizontal: context.getWidth(6),
                                    vertical: context.getHeight(6),
                                  ),
                                  shape: RoundedRectangleBorder(
                                    borderRadius: BorderRadius.circular(8),
                                  ),
                                ),
                                child: Text(
                                  'Open',
                                  style: TextStyle(fontSize: context.getFontSize(12)),
                                ),
                              ),
                            ],
                          ),
                        ),
                      ),
                    ),
                  );
                },
              ),
            );

          },),

                ),
      ),);
  }
}


📐 Available Extensions

ExtensionDescription
context.getWidth(x)Scaled width from reference design
context.getHeight(x)Scaled height from reference design
context.getFontSize(x)Font size scaled to screen
context.getMinSize(x)Minimum scaling factor
context.scaleWidthCurrent width ratio to base
context.scaleHeightCurrent height ratio to base
context.isMobileIs device considered mobile
context.isTabletIs device a tablet
context.isDesktopIs device desktop
context.safePaddingSafe area (notch, status bar, etc)

💡 Why use smart_sizer?

  • Simple and predictable scaling
  • Easy to integrate into any Flutter project
  • Breakpoint support (mobile / tablet / desktop)
  • Useful for localization and text scaling

📄 License

MIT © 2025 Ahmed Shaker

Built with ❤️ for responsive design enthusiasts


For help or contributions, feel free to open issues or PRs on GitHub.

📬 Suggestions? Contact me at GitHub page placeholder.