5-Minute Quickstart
This page gives you a complete runnable screen before the rest of the Getting Started section explains each part in more detail.
1. Add the package
flutter pub add flutter_data_components
2. Replace lib/main.dart
import 'package:flutter/material.dart';
import 'package:flutter_data_components/fdc.dart';
void main() {
runApp(const CustomerApp());
}
class CustomerApp extends StatelessWidget {
const CustomerApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'FD Components Quickstart',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue),
useMaterial3: true,
),
home: const CustomerScreen(),
);
}
}
class CustomerScreen extends StatefulWidget {
const CustomerScreen({super.key});
@override
State<CustomerScreen> createState() => _CustomerScreenState();
}
class _CustomerScreenState extends State<CustomerScreen> {
late final FdcDataSet _customers;
late final Future<void> _loadFuture;
@override
void initState() {
super.initState();
_customers = FdcDataSet(
fields: const <FdcFieldDef>[
FdcIntegerField(
name: 'id',
label: 'ID',
isKey: true,
storage: FdcFieldStorage(updateable: false),
),
FdcStringField(
name: 'company',
label: 'Company',
size: 120,
required: true,
),
FdcStringField(
name: 'city',
label: 'City',
size: 80,
),
FdcDecimalField(
name: 'credit_limit',
label: 'Credit limit',
precision: 12,
scale: 2,
minValue: 0,
),
FdcBooleanField(
name: 'active',
label: 'Active',
defaultValue: true,
),
],
);
_loadFuture = _customers.loadRows(<Map<String, Object?>>[
<String, Object?>{
'id': 1,
'company': 'Northstar Analytics',
'city': 'Seattle',
'credit_limit': 25000,
'active': true,
},
<String, Object?>{
'id': 2,
'company': 'Blue Ridge Supply',
'city': 'Denver',
'credit_limit': 42000,
'active': true,
},
<String, Object?>{
'id': 3,
'company': 'Lakeview Foods',
'city': 'Chicago',
'credit_limit': 18000,
'active': false,
},
]);
}
@override
void dispose() {
_customers.close();
_customers.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Customers')),
body: FutureBuilder<void>(
future: _loadFuture,
builder: (context, snapshot) {
if (snapshot.hasError) {
return Center(
child: Text('Could not load customers: ${snapshot.error}'),
);
}
if (snapshot.connectionState != ConnectionState.done) {
return const Center(child: CircularProgressIndicator());
}
return Padding(
padding: const EdgeInsets.all(12),
child: FdcGrid(
dataSet: _customers,
statusBar: const FdcGridStatusBar(visible: true),
columns: const <FdcGridColumn<dynamic>>[
FdcIntegerColumn<dynamic>(
fieldName: 'id',
width: 80,
readOnly: true,
),
FdcTextColumn<dynamic>(
fieldName: 'company',
width: 220,
),
FdcTextColumn<dynamic>(
fieldName: 'city',
width: 160,
),
FdcDecimalColumn<dynamic>(
fieldName: 'credit_limit',
width: 150,
),
FdcBooleanColumn<dynamic>(
fieldName: 'active',
width: 100,
),
],
),
);
},
),
);
}
}
3. Run the app
flutter run
You now have a typed local dataset bound to an editable grid. The dataset owns schema, records, navigation, edit state, validation, and change tracking; the grid is the interaction surface.
The example uses local mode, so data is loaded with loadRows. Adapter-backed datasets use the same screen model but receive an adapter and call open() instead.
Next: Your First DataSet