flutter_adaptive_util 0.0.3
flutter_adaptive_util: ^0.0.3 copied to clipboard
A comprehensive Flutter package for responsive design with breakpoint management, typography scaling, adaptive spacing, and more.
import 'package:flutter/material.dart';
import 'package:flutter_adaptive_util/flutter_adaptive_util.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Responsive Utils Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: ResponsiveDemoPage(),
);
}
}
class ResponsiveDemoPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: 'Flutter Responsive Utils'.responsiveHeading(level: 1),
backgroundColor: Colors.blue,
foregroundColor: Colors.white,
),
body: ResponsiveContextBuilder(
builder: (context, responsiveContext) {
return SingleChildScrollView(
padding: context.paddingAll,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_buildHeader(context, responsiveContext.breakpoint),
SizedBox(height: context.spacing * 2),
_buildBreakpointInfo(
context, responsiveContext.breakpoint, responsiveContext),
SizedBox(height: context.spacing * 2),
_buildResponsiveGrid(context),
SizedBox(height: context.spacing * 2),
_buildTypographyDemo(context),
SizedBox(height: context.spacing * 2),
_buildSpacingDemo(context),
SizedBox(height: context.spacing * 2),
_buildOrientationDemo(context),
SizedBox(height: context.spacing * 2),
_buildMediaQueryHelpersDemo(context),
SizedBox(height: context.spacing * 2),
_buildResponsiveWidgetsDemo(context),
],
),
);
},
),
);
}
Widget _buildHeader(BuildContext context, Breakpoint breakpoint) {
return Container(
width: double.infinity,
padding: context.paddingAll,
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [Colors.blue, Colors.purple],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
borderRadius: BorderRadius.circular(12),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
'Welcome to Flutter Responsive Utils!'.responsiveHeading(
level: 1,
style: TextStyle(color: Colors.white),
),
SizedBox(height: context.spacing),
'Current Breakpoint: ${breakpoint.name}'.responsiveText(
style: TextStyle(color: Colors.white70),
),
SizedBox(height: context.spacing),
'Screen Size: ${context.screenWidth.round()} x ${context.screenHeight.round()}'
.responsiveText(
style: TextStyle(color: Colors.white70),
),
],
),
);
}
Widget _buildBreakpointInfo(BuildContext context, Breakpoint breakpoint,
ResponsiveContext responsiveContext) {
return Card(
child: Padding(
padding: context.paddingAll,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
'Breakpoint Information'.responsiveHeading(level: 2),
SizedBox(height: context.spacing),
_buildBreakpointRow(context, 'Mobile', responsiveContext.isMobile,
breakpoint == Breakpoint.mobile),
_buildBreakpointRow(context, 'Tablet', responsiveContext.isTablet,
breakpoint == Breakpoint.tablet),
_buildBreakpointRow(context, 'Desktop', responsiveContext.isDesktop,
breakpoint == Breakpoint.desktop),
_buildBreakpointRow(
context,
'Large Desktop',
responsiveContext.isLargeDesktop,
breakpoint == Breakpoint.largeDesktop),
_buildBreakpointRow(
context,
'Extra Large',
responsiveContext.isExtraLarge,
breakpoint == Breakpoint.extraLarge),
],
),
),
);
}
Widget _buildBreakpointRow(
BuildContext context, String name, bool isActive, bool isCurrent) {
return Padding(
padding: EdgeInsets.symmetric(vertical: context.spacing * 0.5),
child: Row(
children: [
Container(
width: 12,
height: 12,
decoration: BoxDecoration(
color: isCurrent
? Colors.green
: (isActive ? Colors.orange : Colors.grey),
shape: BoxShape.circle,
),
),
SizedBox(width: context.spacing),
name.responsiveText(),
Spacer(),
if (isCurrent)
'Current'.responsiveText(
style: TextStyle(
color: Colors.green, fontWeight: FontWeight.bold)),
],
),
);
}
Widget _buildResponsiveGrid(BuildContext context) {
return Card(
child: Padding(
padding: context.paddingAll,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
'Responsive Grid Demo'.responsiveHeading(level: 2),
SizedBox(height: context.spacing),
ResponsiveGrid(
columns: 6, // Reduced from 12 to make items wider
spacing: context.spacing,
childAspectRatio:
0.7, // Smaller ratio = taller items (bigger cards)
children: [
_buildGridCard('Grid Item 1', Colors.blue).asGridItem(
span: 3,
mobileSpan: 6,
tabletSpan: 3,
),
_buildGridCard('Grid Item 2', Colors.green).asGridItem(
span: 3,
mobileSpan: 6,
tabletSpan: 3,
),
_buildGridCard('Grid Item 3', Colors.orange).asGridItem(
span: 2,
mobileSpan: 6,
tabletSpan: 3,
),
_buildGridCard('Grid Item 4', Colors.red).asGridItem(
span: 2,
mobileSpan: 6,
tabletSpan: 3,
),
_buildGridCard('Grid Item 5', Colors.purple).asGridItem(
span: 2,
mobileSpan: 6,
tabletSpan: 6,
),
],
),
],
),
),
);
}
Widget _buildGridCard(String title, Color color) {
return Card(
color: color,
child: Padding(
padding: EdgeInsets.all(16.0),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
title.responsiveHeading(
level: 3,
style: TextStyle(color: Colors.white),
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
SizedBox(height: 8.0),
'This grid item adapts to different screen sizes.'.responsiveText(
style: TextStyle(color: Colors.white70),
maxLines: 3,
overflow: TextOverflow.ellipsis,
),
],
),
),
);
}
Widget _buildTypographyDemo(BuildContext context) {
return Card(
child: Padding(
padding: context.paddingAll,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
'Responsive Typography Demo'.responsiveHeading(level: 2),
SizedBox(height: context.spacing),
'This is a responsive heading level 1'.responsiveHeading(level: 1),
SizedBox(height: context.spacing * 0.5),
'This is a responsive heading level 2'.responsiveHeading(level: 2),
SizedBox(height: context.spacing * 0.5),
'This is a responsive heading level 3'.responsiveHeading(level: 3),
SizedBox(height: context.spacing * 0.5),
'This is responsive body text that scales with screen size.'
.responsiveText(),
SizedBox(height: context.spacing * 0.5),
'This is smaller responsive text.'.responsiveText(scale: 0.8),
SizedBox(height: context.spacing * 0.5),
'This is larger responsive text.'.responsiveText(scale: 1.2),
],
),
),
);
}
Widget _buildSpacingDemo(BuildContext context) {
return Card(
child: Padding(
padding: context.paddingAll,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
'Responsive Spacing Demo'.responsiveHeading(level: 2),
SizedBox(height: context.spacing),
Container(
padding: context.paddingAll,
margin: context.paddingSymmetric(horizontal: context.spacing),
decoration: BoxDecoration(
color: Colors.blue.withValues(alpha: .1),
border: Border.all(color: Colors.blue),
borderRadius: BorderRadius.circular(8),
),
child: 'This container uses responsive padding and margin'
.responsiveText(),
),
SizedBox(height: context.spacing),
Row(
children: [
Container(
width: context.spacingSize(SpacingSize.xs),
height: context.spacingSize(SpacingSize.xs),
color: Colors.red,
),
SizedBox(width: context.spacing * 0.5),
Container(
width: context.spacingSize(SpacingSize.sm),
height: context.spacingSize(SpacingSize.sm),
color: Colors.orange,
),
SizedBox(width: context.spacing * 0.5),
Container(
width: context.spacingSize(SpacingSize.md),
height: context.spacingSize(SpacingSize.md),
color: Colors.yellow,
),
SizedBox(width: context.spacing * 0.5),
Container(
width: context.spacingSize(SpacingSize.lg),
height: context.spacingSize(SpacingSize.lg),
color: Colors.green,
),
],
),
],
),
),
);
}
Widget _buildOrientationDemo(BuildContext context) {
return Card(
child: Padding(
padding: context.paddingAll,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
'Orientation Demo'.responsiveHeading(level: 2),
SizedBox(height: context.spacing),
ResponsiveOrientationLayout(
portrait: Container(
padding: context.paddingAll,
color: Colors.blue.withValues(alpha: .1),
child: 'Portrait Layout'.responsiveText(),
),
landscape: Container(
padding: context.paddingAll,
color: Colors.green.withValues(alpha: .1),
child: 'Landscape Layout'.responsiveText(),
),
),
SizedBox(height: context.spacing),
Container(
padding: context.orientationPadding(
portrait: EdgeInsets.all(16.0),
landscape: EdgeInsets.all(24.0),
fallback: EdgeInsets.all(16.0),
),
decoration: BoxDecoration(
color: context.isPortrait
? Colors.purple.withValues(alpha: .1)
: Colors.orange.withValues(alpha: .1),
border: Border.all(
color: context.isPortrait ? Colors.purple : Colors.orange,
),
borderRadius: BorderRadius.circular(8),
),
child:
'Orientation: ${context.isPortrait ? "Portrait" : "Landscape"}'
.responsiveText(),
),
],
),
),
);
}
Widget _buildMediaQueryHelpersDemo(BuildContext context) {
return Card(
child: Padding(
padding: context.paddingAll,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
'Media Query Helpers Demo'.responsiveHeading(level: 2),
SizedBox(height: context.spacing),
// ResponsiveValue demo
Container(
padding: context.paddingAll,
decoration: BoxDecoration(
color: Colors.blue.withValues(alpha: .1),
borderRadius: BorderRadius.circular(8),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
'responsiveValue<T>()'.responsiveHeading(level: 3),
SizedBox(height: context.spacing * 0.5),
Container(
padding: context.paddingAll,
color: Colors.white,
child: context
.responsiveValue<String>(
mobile: 'Mobile Value',
tablet: 'Tablet Value',
desktop: 'Desktop Value',
largeDesktop: 'Large Desktop Value',
extraLarge: 'Extra Large Value',
fallback: 'Default Value',
)
.responsiveText(),
),
],
),
),
SizedBox(height: context.spacing),
// ResponsiveDouble demo
Container(
padding: context.paddingAll,
decoration: BoxDecoration(
color: Colors.green.withValues(alpha: .1),
borderRadius: BorderRadius.circular(8),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
'responsiveDouble()'.responsiveHeading(level: 3),
SizedBox(height: context.spacing * 0.5),
Container(
width: double.infinity,
height: context.responsiveDouble(
mobile: 40.0,
tablet: 50.0,
desktop: 60.0,
largeDesktop: 70.0,
extraLarge: 80.0,
fallback: 50.0,
),
decoration: BoxDecoration(
color: Colors.green.withValues(alpha: .3),
borderRadius: BorderRadius.circular(8),
),
child: Center(
child: 'Height: ${context.responsiveDouble(
mobile: 40.0,
tablet: 50.0,
desktop: 60.0,
largeDesktop: 70.0,
extraLarge: 80.0,
fallback: 50.0,
).toStringAsFixed(0)}px'
.responsiveText(),
),
),
],
),
),
SizedBox(height: context.spacing),
// ResponsiveInt demo
Container(
padding: context.paddingAll,
decoration: BoxDecoration(
color: Colors.orange.withValues(alpha: .1),
borderRadius: BorderRadius.circular(8),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
'responsiveInt()'.responsiveHeading(level: 3),
SizedBox(height: context.spacing * 0.5),
Row(
children: List.generate(
context.responsiveInt(
mobile: 2,
tablet: 3,
desktop: 4,
largeDesktop: 5,
extraLarge: 6,
fallback: 3,
),
(index) => Padding(
padding: EdgeInsets.only(right: context.spacing * 0.5),
child: Container(
width: 30,
height: 30,
decoration: BoxDecoration(
color: Colors.orange,
shape: BoxShape.circle,
),
child: Center(
child: '${index + 1}'.responsiveText(
style: TextStyle(color: Colors.white),
),
),
),
),
),
),
SizedBox(height: context.spacing * 0.5),
'Number of items: ${context.responsiveInt(
mobile: 2,
tablet: 3,
desktop: 4,
largeDesktop: 5,
extraLarge: 6,
fallback: 3,
)}'
.responsiveText(),
],
),
),
SizedBox(height: context.spacing),
// ResponsiveBool demo
Container(
padding: context.paddingAll,
decoration: BoxDecoration(
color: Colors.purple.withValues(alpha: .1),
borderRadius: BorderRadius.circular(8),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
'responsiveBool()'.responsiveHeading(level: 3),
SizedBox(height: context.spacing * 0.5),
Container(
padding: context.paddingAll,
decoration: BoxDecoration(
color: context.responsiveValue<Color>(
mobile: Colors.red.withValues(alpha: .2),
tablet: Colors.blue.withValues(alpha: .2),
desktop: Colors.green.withValues(alpha: .2),
largeDesktop: Colors.purple.withValues(alpha: .2),
extraLarge: Colors.orange.withValues(alpha: .2),
fallback: Colors.grey.withValues(alpha: .2),
),
borderRadius: BorderRadius.circular(8),
),
child: Row(
children: [
Icon(
context.responsiveValue<IconData>(
mobile: Icons.phone_android,
tablet: Icons.tablet,
desktop: Icons.desktop_windows,
largeDesktop: Icons.desktop_mac,
extraLarge: Icons.tv,
fallback: Icons.device_unknown,
),
color: context.responsiveValue<Color>(
mobile: Colors.red,
tablet: Colors.blue,
desktop: Colors.green,
largeDesktop: Colors.purple,
extraLarge: Colors.orange,
fallback: Colors.grey,
),
),
SizedBox(width: context.spacing),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
'Show icon: ${context.responsiveBool(
mobile: true,
tablet: true,
desktop: true,
largeDesktop: true,
extraLarge: true,
fallback: false,
)}'
.responsiveText(),
SizedBox(height: context.spacing * 0.25),
'Enable feature: ${context.responsiveBool(
mobile: false,
tablet: true,
desktop: true,
largeDesktop: true,
extraLarge: true,
fallback: false,
)}'
.responsiveText(),
],
),
),
],
),
),
],
),
),
],
),
),
);
}
Widget _buildResponsiveWidgetsDemo(BuildContext context) {
return Card(
child: Padding(
padding: context.paddingAll,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
'Responsive Widgets Demo'.responsiveHeading(level: 2),
SizedBox(height: context.spacing),
// ResponsiveBuilder demo
Container(
padding: context.paddingAll,
decoration: BoxDecoration(
color: Colors.blue.withValues(alpha: .1),
borderRadius: BorderRadius.circular(8),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
'ResponsiveBuilder'.responsiveHeading(level: 3),
SizedBox(height: context.spacing * 0.5),
ResponsiveBuilder(
builder: (context, breakpoint, size) {
return Container(
padding: context.paddingAll,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(8),
),
child: Column(
children: [
'Breakpoint: ${breakpoint.name}'.responsiveText(),
SizedBox(height: context.spacing * 0.5),
'Size: ${size.width.round()} x ${size.height.round()}'
.responsiveText(),
],
),
);
},
),
],
),
),
SizedBox(height: context.spacing),
// ResponsiveLayout demo
Container(
padding: context.paddingAll,
decoration: BoxDecoration(
color: Colors.green.withValues(alpha: .1),
borderRadius: BorderRadius.circular(8),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
'ResponsiveLayout'.responsiveHeading(level: 3),
SizedBox(height: context.spacing * 0.5),
ResponsiveLayout(
mobile: Container(
padding: context.paddingAll,
decoration: BoxDecoration(
color: Colors.red.withValues(alpha: .2),
borderRadius: BorderRadius.circular(8),
),
child: 'Mobile Layout'.responsiveText(),
),
tablet: Container(
padding: context.paddingAll,
decoration: BoxDecoration(
color: Colors.orange.withValues(alpha: .2),
borderRadius: BorderRadius.circular(8),
),
child: 'Tablet Layout'.responsiveText(),
),
desktop: Container(
padding: context.paddingAll,
decoration: BoxDecoration(
color: Colors.green.withValues(alpha: .2),
borderRadius: BorderRadius.circular(8),
),
child: 'Desktop Layout'.responsiveText(),
),
largeDesktop: Container(
padding: context.paddingAll,
decoration: BoxDecoration(
color: Colors.blue.withValues(alpha: .2),
borderRadius: BorderRadius.circular(8),
),
child: 'Large Desktop Layout'.responsiveText(),
),
extraLarge: Container(
padding: context.paddingAll,
decoration: BoxDecoration(
color: Colors.purple.withValues(alpha: .2),
borderRadius: BorderRadius.circular(8),
),
child: 'Extra Large Layout'.responsiveText(),
),
fallback: Container(
padding: context.paddingAll,
decoration: BoxDecoration(
color: Colors.grey.withValues(alpha: .2),
borderRadius: BorderRadius.circular(8),
),
child: 'Fallback Layout'.responsiveText(),
),
),
],
),
),
SizedBox(height: context.spacing),
// ResponsiveConditionalBuilder demo
Container(
padding: context.paddingAll,
decoration: BoxDecoration(
color: Colors.orange.withValues(alpha: .1),
borderRadius: BorderRadius.circular(8),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
'ResponsiveConditionalBuilder'.responsiveHeading(level: 3),
SizedBox(height: context.spacing * 0.5),
ResponsiveConditionalBuilder(
condition: (breakpoint, size) =>
breakpoint == Breakpoint.desktop ||
breakpoint == Breakpoint.largeDesktop ||
breakpoint == Breakpoint.extraLarge,
builder: (context, breakpoint, size) {
return Container(
padding: context.paddingAll,
decoration: BoxDecoration(
color: Colors.green.withValues(alpha: .2),
borderRadius: BorderRadius.circular(8),
),
child: 'Desktop or larger screen detected!'
.responsiveText(),
);
},
fallback: Container(
padding: context.paddingAll,
decoration: BoxDecoration(
color: Colors.red.withValues(alpha: .2),
borderRadius: BorderRadius.circular(8),
),
child: 'Mobile or Tablet screen'.responsiveText(),
),
),
],
),
),
SizedBox(height: context.spacing),
// ResponsiveContentBuilder demo
Container(
padding: context.paddingAll,
decoration: BoxDecoration(
color: Colors.purple.withValues(alpha: .1),
borderRadius: BorderRadius.circular(8),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
'ResponsiveContentBuilder'.responsiveHeading(level: 3),
SizedBox(height: context.spacing * 0.5),
ResponsiveContentBuilder(
mobile: (context, size) => Container(
padding: context.paddingAll,
decoration: BoxDecoration(
color: Colors.red.withValues(alpha: .2),
borderRadius: BorderRadius.circular(8),
),
child: 'Mobile Content (${size.width.round()}px)'
.responsiveText(),
),
tablet: (context, size) => Container(
padding: context.paddingAll,
decoration: BoxDecoration(
color: Colors.orange.withValues(alpha: .2),
borderRadius: BorderRadius.circular(8),
),
child: 'Tablet Content (${size.width.round()}px)'
.responsiveText(),
),
desktop: (context, size) => Container(
padding: context.paddingAll,
decoration: BoxDecoration(
color: Colors.green.withValues(alpha: .2),
borderRadius: BorderRadius.circular(8),
),
child: 'Desktop Content (${size.width.round()}px)'
.responsiveText(),
),
fallback: (context, size) => Container(
padding: context.paddingAll,
decoration: BoxDecoration(
color: Colors.grey.withValues(alpha: .2),
borderRadius: BorderRadius.circular(8),
),
child: 'Fallback Content'.responsiveText(),
),
),
],
),
),
],
),
),
);
}
}