responsive_scaler 1.0.1
responsive_scaler: ^1.0.1 copied to clipboard
A Flutter package for consistent responsive scaling of text, icons, and spacing based on screen size, helping maintain UI proportionality across devices.
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:responsive_framework/responsive_framework.dart';
import 'package:responsive_scaler/responsive_scaler.dart';
void main() {
WidgetsFlutterBinding.ensureInitialized();
// Initialization - this is where the magic starts
ResponsiveScaler.init(
designWidth: 412, designHeight: 927, maxScale: 1.9, minScale: 0.8);
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Responsive Login Demo',
theme: ThemeData(primarySwatch: Colors.blue, useMaterial3: true),
// This is crucial. It captures the screen data on each rebuild.
builder: (context, child) {
final scaledChild = ResponsiveScaler.scale(
context: context,
child: child!,
useMaxAccessibility: false,
);
return ResponsiveBreakpoints.builder(
breakpoints: [
const Breakpoint(start: 0, end: 450, name: MOBILE),
const Breakpoint(start: 451, end: 800, name: TABLET),
const Breakpoint(start: 801, end: 1920, name: DESKTOP),
],
child: scaledChild,
);
},
home: const LoginPage(),
);
}
}
class LoginPage extends StatelessWidget {
const LoginPage({super.key});
@override
Widget build(BuildContext context) {
bool isMobile = ResponsiveBreakpoints.of(context).smallerThan(TABLET);
return Scaffold(
body: SingleChildScrollView(
child: Center(
child: Padding(
padding: EdgeInsets.all(24.r),
child: ResponsiveRowColumn(
layout: isMobile
? ResponsiveRowColumnType.COLUMN
: ResponsiveRowColumnType.ROW,
rowMainAxisAlignment: MainAxisAlignment.center,
columnCrossAxisAlignment: CrossAxisAlignment.center,
children: [
// Illustration
ResponsiveRowColumnItem(
rowFlex: 1,
child: Padding(
padding: EdgeInsets.only(
bottom: isMobile ? 24.r : 0,
right: isMobile ? 0 : 24.r,
),
child: SvgPicture.asset(
"assets/login_illustration.svg",
height: isMobile
? 200.scale(maxValue: 250, minValue: 150)
: 300.scale(maxValue: 350, minValue: 250),
),
),
),
// Login Form
ResponsiveRowColumnItem(
rowFlex: 1,
child: _buildLoginForm(context),
),
],
),
),
),
),
);
}
Widget _buildLoginForm(BuildContext context) {
final theme = Theme.of(context);
return SingleChildScrollView(
child: Container(
padding: EdgeInsets.all(16.r),
constraints: BoxConstraints(
maxWidth: 400
.scale(maxValue: 500, minValue: 250)), // Constrain form width
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(16),
boxShadow: const [
BoxShadow(
color: Colors.black12,
blurRadius: 12,
offset: Offset(0, 6),
),
],
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
// Text scales automatically
Text("Welcome Back 👋", style: theme.textTheme.headlineMedium),
SizedBox(height: 16.r),
// Email
TextField(
decoration: InputDecoration(
labelText: "Email",
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
),
),
),
SizedBox(height: 16.r),
// Password
TextField(
obscureText: true,
decoration: InputDecoration(
labelText: "Password",
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
),
),
),
SizedBox(height: 8.r),
// Button
SizedBox(
width: double.infinity,
child: ElevatedButton(
onPressed: () {},
style: ElevatedButton.styleFrom(
backgroundColor: const Color(0xFF6c63ff),
foregroundColor: Colors.white,
padding: EdgeInsets.symmetric(
vertical: 16.r,
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
),
// Text scales automatically
child: Text("Login", style: theme.textTheme.bodyLarge),
),
),
],
),
),
);
}
}