mo_adapt 0.1.0
mo_adapt: ^0.1.0 copied to clipboard
Wrap your app once and every UI dimension - text, padding, icons, radii, widths, heights - scales proportionally to the screen from a reference design size. No .w/.h/.sp accessors needed.
import 'package:flutter/material.dart';
import 'package:mo_adapt/mo_adapt.dart';
void main() {
runApp(
// The only mo_adapt-specific line in the whole app: wrap it once.
const MoAdapt(
designSize: Size(390, 844),
child: ExampleApp(),
),
);
}
class ExampleApp extends StatelessWidget {
const ExampleApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'mo_adapt example',
theme: ThemeData(colorSchemeSeed: Colors.teal),
home: const HomePage(),
);
}
}
/// A perfectly ordinary page: every dimension below is a plain fixed number
/// taken straight from a 390x844 design. mo_adapt scales all of them.
class HomePage extends StatelessWidget {
const HomePage({super.key});
@override
Widget build(BuildContext context) {
final MoAdaptData adapt = MoAdapt.of(context);
return Scaffold(
appBar: AppBar(title: const Text('mo_adapt')),
body: ListView(
padding: const EdgeInsets.all(16),
children: <Widget>[
const Text(
'Fixed sizes, scaled automatically',
style: TextStyle(fontSize: 22, fontWeight: FontWeight.bold),
),
const SizedBox(height: 8),
Text(
'Current scale: ${adapt.scale.toStringAsFixed(2)}x '
'(screen ${adapt.screenSize.width.toStringAsFixed(0)}x'
'${adapt.screenSize.height.toStringAsFixed(0)})',
style: const TextStyle(fontSize: 14),
),
const SizedBox(height: 24),
Container(
height: 120,
decoration: BoxDecoration(
color: Colors.teal.shade100,
borderRadius: BorderRadius.circular(20),
),
alignment: Alignment.center,
child: const Text(
'120 tall, radius 20',
style: TextStyle(fontSize: 16),
),
),
const SizedBox(height: 16),
Row(
children: <Widget>[
const Icon(Icons.star, size: 32),
const SizedBox(width: 12),
const Expanded(
child: Text(
'Icon size 32, gap 12, font 16 — all from the design.',
style: TextStyle(fontSize: 16),
),
),
],
),
const SizedBox(height: 24),
FilledButton(
onPressed: () {
showDialog<void>(
context: context,
builder: (BuildContext context) => AlertDialog(
title: const Text('Dialogs scale too'),
content: const Text(
'Overlays, dialogs, and bottom sheets live inside the '
'scaled subtree, so they stay proportional as well.',
),
actions: <Widget>[
TextButton(
onPressed: () => Navigator.pop(context),
child: const Text('OK'),
),
],
),
);
},
child: const Text('Show a dialog'),
),
],
),
);
}
}