Value Prop Onboarding
Loading preview
Starting the Flutter app
A Flutter onboarding value-proposition screen with benefit rows and a get-started button.
import 'package:flutter/material.dart';
class _Benefit {
final IconData icon;
final String title;
final String body;
const _Benefit(this.icon, this.title, this.body);
}
class ValueProp extends StatelessWidget {
const ValueProp({super.key});
static const _benefits = [
_Benefit(Icons.savings_outlined, 'Save more',
'Automatic rules move money to savings for you.'),
_Benefit(Icons.pie_chart_outline, 'See everything',
'All your accounts in one clear dashboard.'),
_Benefit(Icons.shield_moon_outlined, 'Stay protected',
'Bank-level security and instant fraud alerts.'),
];
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
final scheme = theme.colorScheme;
return Scaffold(
body: SafeArea(
child: Padding(
padding: const EdgeInsets.all(28),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
const SizedBox(height: 12),
Icon(Icons.account_balance_wallet_outlined,
size: 56, color: scheme.primary),
const SizedBox(height: 24),
Text('Money, made simple',
style: theme.textTheme.headlineMedium
?.copyWith(fontWeight: FontWeight.bold)),
const SizedBox(height: 8),
Text('Everything you need to spend, save, and grow.',
style: theme.textTheme.bodyLarge
?.copyWith(color: scheme.onSurfaceVariant)),
const SizedBox(height: 36),
for (final b in _benefits)
Padding(
padding: const EdgeInsets.only(bottom: 24),
child: Row(
children: [
CircleAvatar(
radius: 26,
backgroundColor: scheme.primaryContainer,
child: Icon(b.icon,
color: scheme.onPrimaryContainer),
),
const SizedBox(width: 16),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(b.title,
style: theme.textTheme.titleMedium
?.copyWith(fontWeight: FontWeight.w600)),
const SizedBox(height: 2),
Text(b.body,
style: theme.textTheme.bodyMedium?.copyWith(
color: scheme.onSurfaceVariant)),
],
),
),
],
),
),
const Spacer(),
SizedBox(
height: 52,
child: FilledButton(
onPressed: () => _showDemo(context, 'Get started (demo)'), child: const Text('Get started')),
),
const SizedBox(height: 12),
Center(
child: TextButton(
onPressed: () => _showDemo(context, 'Sign in (demo)'), child: const Text('I already have an account')),
),
],
),
),
),
);
}
}
void _showDemo(BuildContext context, String message) {
ScaffoldMessenger.of(context)
..hideCurrentSnackBar()
..showSnackBar(SnackBar(content: Text(message)));
}
Add it to your project
Copies the Dart source into your app, so you own it. Flutter SDK only, no extra packages.
First time? Run dart pub global activate fluttertemplates_dev, or read the CLI guide.
How it works
A single stateless screen, no paging. A for loop over _benefits emits an icon-and-text row per _Benefit, then a Spacer pushes the two buttons to the bottom. Since the whole thing is a plain Column, large text settings or short phones will overflow instead of scrolling. Both buttons show a demo SnackBar.
Adapting it
- Edit
_benefitsand the headline strings; the finance copy is sample text. - Route
Get startedto sign-up and theTextButtonto sign-in. - For small devices, put the list in an
Expandedscrollable and keep the buttons outside it.