Irbisa · Cheatsheet
Flutter Fundamentals
Widget tree, StatelessWidget, StatefulWidget, BuildContext
What is Flutter, how does it differ from React Native and other cross-platform frameworks, and what are its limitations?
Why does Flutter use Dart rather than JavaScript or Kotlin?
What are the layers of Flutter's architecture (framework, engine, embedder) and what does each one do?
What is the difference between imperative and declarative UI, and why is Flutter called declarative?
What does "everything is a widget" mean, and why are padding and opacity separate widgets instead of properties?
// Composition: one job per wrapper, and the nesting *is* the layoutclass PriceTag extends StatelessWidget { const PriceTag({super.key, required this.label}); final String label; @override…What is the difference between StatelessWidget and StatefulWidget, and why not make every widget stateful?
// Stateless: a pure function of its constructor argumentsclass GreetingCard extends StatelessWidget { const GreetingCard({super.key, required this.name}); final String name; @override…What is
BuildContext, what does it represent in the tree, and why do you need it?Widget build(BuildContext context) { return Theme( data: ThemeData.dark(), // wrong: this context sits ABOVE the Theme, so it reads the outer theme child: Text('Hi', style: Theme.of(context).textTheme.bodyLarge), );…In what order do a State object's lifecycle methods run, from creation to disposal?
class ProfileForm extends StatefulWidget { const ProfileForm({super.key, required this.name}); final String name; @override State<ProfileForm> createState() => _ProfileFormState();…What is the difference between
main()andrunApp(), and when do you needWidgetsFlutterBinding.ensureInitialized()?Future<void> main() async { WidgetsFlutterBinding.ensureInitialized(); // plugins are called below await Firebase.initializeApp( options: DefaultFirebaseOptions.currentPlatform, ); await SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);…What do MaterialApp and Scaffold actually provide, and what breaks without them?
void main() => runApp(const MyApp()); class MyApp extends StatelessWidget { const MyApp({super.key}); @override…What is the difference between hot reload, hot restart, and full restart?
What is
pubspec.yamlfor, and what does^mean in a dependency version?name: shop_appdescription: Online store client.publish_to: noneversion: 1.4.0+12 # version name + build number environment:…The app runs on mobile but crashes on the web at
Platform.isIOSwith "Unsupported operation: Platform._operatingSystem". How should a Flutter app branch on platform?// wrong: compiles for web but throws UnsupportedError when it runs// import 'dart:io' show Platform;// final isApple = Platform.isIOS || Platform.isMacOS; import 'package:flutter/cupertino.dart';import 'package:flutter/foundation.dart';…How do you debug a Flutter app, and what is the difference between
print,debugPrintandlog?import 'dart:developer' as developer;import 'package:flutter/foundation.dart'; void onCheckoutFailed(Order order, Object error) { if (kDebugMode) { debugPrint('checkout ${order.id}: $error'); // throttled, safe for long text…What are Flutter's debug, profile and release modes, and how do JIT and AOT compilation fit into them?
flutter run # debug: JIT, hot reload, asserts onflutter run --profile # AOT + tracing, real device onlyflutter run --release # AOT, what users get flutter build apk # build defaults to releaseflutter build appbundle --obfuscate --split-debug-info=build/symbols…A screen fires its API request from inside build() and hammers the server. Why does build run so often, and where does the call belong?
// wrong: a new request on every rebuild@overrideWidget build(BuildContext context) { return FutureBuilder( future: api.loadUser(widget.id), // rebuilt = refetched builder: (context, snap) => UserView(snap.data),…Should a long build method be split into private
_buildHeader()helpers or into separate widget classes?// wrong: helper method; one Element, rebuilt with the whole pageWidget _buildHeader(BuildContext context) => Text('Profile', style: Theme.of(context).textTheme.headlineSmall); // right: widget classes; own Elements, const-able, independently rebuiltclass ProfilePage2 extends StatelessWidget {…A counter is kept as a field on the StatefulWidget itself and setState updates it, but the number keeps resetting. Why?
// wrong: state on the widget; the field dies with the instanceclass Counter extends StatefulWidget { // analyzer: must_be_immutable Counter({super.key}); int count = 0; // recreated by every parent build @override…This screen should greet the user with a dialog when it opens, but it throws instead. What is wrong and how do you fix it?
class _WelcomeState extends State<Welcome> { @override void initState() { super.initState(); showDialog<void>( context: context, builder: (_) => const AlertDialog(title: Text('Welcome!')), ); } @override Widget build(BuildContext context) => const Scaffold(body: Placeholder());}Tick row B in this list, then tap "Remove first", and the tick jumps to C. Why, and what is the fix?
class _TodoListState extends State<TodoList> { final items = ['A', 'B', 'C']; @override Widget build(BuildContext context) => Column( children: [ // CheckTile is stateful: it keeps its own `checked` bool for (final item in items) CheckTile(label: item), TextButton( onPressed: () => setState(() => items.removeAt(0)), child: const Text('Remove first'), ), ], );}Find the bug: in a tablet master–detail layout, picking another user in the list still shows the first user's details.
class _UserDetailsState extends State<UserDetails> { late Future<User> _user; @override void initState() { super.initState(); _user = widget.repo.loadUser(widget.userId); } @override Widget build(BuildContext context) => FutureBuilder<User>( future: _user, builder: (context, snap) => Text(snap.data?.name ?? 'Loading…'), );}Find the bug: after tapping Save, crash reports show an unhandled exception from the save handler.
class _EditNameState extends State<EditName> { final _name = TextEditingController(); Future<void> _save() async { await widget.api.saveName(_name.text); ScaffoldMessenger.of(context) .showSnackBar(const SnackBar(content: Text('Saved'))); Navigator.of(context).pop(); } @override void dispose() { _name.dispose(); super.dispose(); }}How does your app find out that it went to the background, and what should you do there?
class _PlayerState extends State<Player> with WidgetsBindingObserver { final _controller = VideoController(); @override void initState() { super.initState();…A CTO asks whether the next product should be Flutter, Kotlin Multiplatform with Compose Multiplatform, or two native apps. What do you weigh?