Skip to content

Dart and Flutter Basics Interview Questions for Mobile App Development

25 Dart and Flutter Basics questions with answers for mobile app development roles — 11 easy, 11 medium, 3 hard.

About Dart and Flutter Basics

Flutter uses Dart and a widget-based UI rendered by its own engine. Learn null safety, async-await, streams, isolates, records and patterns, stateless and stateful widgets, the widget lifecycle, keys, layouts and forms. Expect live coding tasks such as building a list screen and questions on how Flutter's layout and rendering pipeline work.

Sheet progressStart practicing
3 QUESTIONS FREESign up to unlock the full question bank and track your progress.Unlock every question and answer, then continue practising company-wise and package-wise.
3 questions free Unlock the rest in seconds
01

What is Dart and why does Flutter use it?

Save to ▾
Show answer
Dart is a typed, object-oriented language created for client development. Flutter uses it because Dart supports JIT compilation for fast hot reload in development and AOT compilation to native machine code for fast release apps. Dart has sound null safety, async-await, isolates for concurrency, and a garbage collector optimised for many short-lived objects, which suits Flutter's frequent widget rebuilding.
02

Explain sound null safety in Dart.

Save to ▾
Show answer
Since Dart 3, all code is null safe. Types are non-nullable by default, so String cannot hold null while String? can. The compiler forces you to handle nulls with checks, the ?. and ?? operators, or the ! operator which throws if null. The late keyword declares a non-null variable initialised later. Sound means the compiler can trust non-null types completely, enabling optimisations and preventing many runtime null errors.
03

What is the difference between final and const in Dart?

Save to ▾
Show answer
final means a variable is assigned once at runtime and cannot be reassigned. const means the value is a compile-time constant and deeply immutable. In Flutter, const constructors like const Text("Hello") let the framework reuse the same widget instance across rebuilds, skipping unnecessary work. Use const wherever possible for widgets with fixed values; the linter rule prefer_const_constructors helps enforce it.
04

What is the difference between StatelessWidget and StatefulWidget?

Save to ▾
Show answer
A StatelessWidget has no mutable state; its build output depends only on constructor parameters and inherited data. A StatefulWidget creates a State object that persists across rebuilds and holds mutable data; calling setState marks it dirty so build runs again. Use stateful widgets for local UI state like animations, text controllers or toggles, and lift shared or business state into a state management solution.
05

How do Future, async and await work in Dart?

Save to ▾
Show answer
A Future represents a value that will be available later, like an HTTP response. Marking a function async lets it use await, which pauses that function until the Future completes without blocking the event loop. Errors are handled with try-catch. Dart runs on a single-threaded event loop per isolate, so awaiting network calls keeps the UI responsive. Use Future.wait to run independent futures concurrently.
06

Write a simple counter using StatefulWidget and setState.

Save to ▾
Show answer
class Counter extends StatefulWidget { const Counter({super.key}); @override State<Counter> createState() => _CounterState(); } class _CounterState extends State<Counter> { int _count = 0; @override Widget build(BuildContext context) => Column( mainAxisSize: MainAxisSize.min, children: [ Text('Count: $_count'), FilledButton( onPressed: () => setState(() => _count++), child: const Text('Add'), ), ], ); }
07

Explain Row, Column, Expanded and Flexible in Flutter layouts.

Save to ▾
Show answer
Row lays out children horizontally and Column vertically, with mainAxisAlignment and crossAxisAlignment controlling placement. Expanded forces a child to fill remaining space along the main axis, and Flexible lets a child take up to its share but be smaller. Using flex values divides space proportionally. A common error is an unbounded width or height, such as a ListView inside a Column without Expanded, which throws a layout exception.
08

What is the difference between ListView and ListView.builder?

Save to ▾
Show answer
The default ListView constructor builds all children at once, which is fine for a few items. ListView.builder builds items lazily as they scroll into view, using itemBuilder and itemCount, so it handles long or infinite lists efficiently. For mixed scrolling content like headers, grids and lists together, use CustomScrollView with slivers. For large lists, also set item extent or use prototypeItem to improve scroll performance.
09

A Flutter screen shows a yellow and black overflow stripe on small phones. How do you fix it?

Save to ▾
Show answer
The overflow stripe means content exceeds the available space, often a Row with long text or a Column taller than the screen. Wrap text in Expanded or Flexible with overflow ellipsis, make the screen scrollable with SingleChildScrollView or a ListView, use LayoutBuilder to adapt for narrow widths, and avoid fixed heights. Also handle the keyboard by allowing the content to scroll when it opens.
10

Write a Dart model class with fromJson and toJson.

Save to ▾
Show answer
class Product { const Product({required this.id, required this.name, required this.price}); final String id; final String name; final double price; factory Product.fromJson(Map<String, dynamic> json) => Product( id: json['id'] as String, name: json['name'] as String, price: (json['price'] as num).toDouble(), ); Map<String, dynamic> toJson() => {'id': id, 'name': name, 'price': price}; } // For larger apps use json_serializable or freezed to generate this.
11

Describe a time you helped a teammate who was stuck on a problem.

Save to ▾
Show answer
Situation: a new teammate spent two days on a Flutter layout that kept overflowing. Task: help without taking over. Action: I sat with them, showed how to use the widget inspector to see constraints, and explained the constraints go down, sizes go up rule with their own screen. Result: they fixed it in an hour and later solved similar issues alone. I also added the explanation to our team wiki.
12

What is BuildContext?

Save to ▾
Show answer
BuildContext is a handle to a widget's location in the element tree. It is used to look up inherited data like Theme.of(context), MediaQuery and Navigator, and providers. Each widget's build method gets its own context. Common mistakes are using a context from above a widget that provides data, or using a context after an async gap when the widget may be unmounted; check context.mounted before using it after await.
13

Explain the StatefulWidget lifecycle methods.

Save to ▾
Show answer
createState creates the State. initState runs once for setup like controllers and subscriptions; do not use inherited widgets there. didChangeDependencies runs after initState and when inherited data changes. build runs on every rebuild. didUpdateWidget runs when the parent rebuilds with new configuration. dispose runs when removed permanently, where you cancel streams, dispose controllers and timers to avoid memory leaks.
14

What are keys in Flutter and when do you need them?

Save to ▾
Show answer
Keys help Flutter match widgets to existing elements and state when the widget list changes. Without keys, Flutter matches by type and position, so reordering or removing items in a list of stateful widgets can attach state to the wrong item. Use ValueKey with a unique ID for list items, UniqueKey to force recreation, and GlobalKey rarely, for accessing state across the tree such as a Form.
15

What is a Stream in Dart and how is it used in Flutter?

Save to ▾
Show answer
A Stream delivers a sequence of asynchronous events, such as real-time database updates, location changes or WebSocket messages. You listen with listen() or await for, and transform with map, where and debounce from packages. Single-subscription streams allow one listener; broadcast streams allow many. In Flutter, StreamBuilder rebuilds UI on each event. Always cancel subscriptions in dispose to prevent leaks.
16

What are isolates and when should you use them?

Save to ▾
Show answer
Isolates are Dart's units of concurrency, each with its own memory and event loop, communicating by messages. Heavy CPU work like parsing a large JSON file, image processing or encryption on the main isolate causes jank. Use Isolate.run or compute to run such work in a separate isolate and return the result. For network or file I/O, async-await is enough because that work is not CPU-bound.
17

Write a Dart sealed class for API results and handle it with an exhaustive switch.

Save to ▾
Show answer
sealed class Result<T> {} class Success<T> extends Result<T> { Success(this.data); final T data; } class Failure<T> extends Result<T> { Failure(this.message); final String message; } Widget view(Result<List<String>> r) => switch (r) { Success(:final data) => ListView(children: [for (final s in data) Text(s)]), Failure(:final message) => Center(child: Text(message)), };
18

Write a Flutter screen that fetches a list from an API using FutureBuilder.

Save to ▾
Show answer
class UsersPage extends StatefulWidget { const UsersPage({super.key}); @override State<UsersPage> createState() => _UsersPageState(); } class _UsersPageState extends State<UsersPage> { late final Future<List<User>> _future = api.fetchUsers(); @override Widget build(BuildContext context) => FutureBuilder<List<User>>( future: _future, builder: (context, snap) { if (snap.connectionState != ConnectionState.done) { return const Center(child: CircularProgressIndicator()); } if (snap.hasError) return const Center(child: Text('Something went wrong')); final users = snap.data!; return ListView.builder( itemCount: users.length, itemBuilder: (_, i) => ListTile(title: Text(users[i].name)), ); }, ); }
19

After an API call finishes, the app throws an error about using BuildContext across async gaps or setState after dispose. How do you fix it?

Save to ▾
Show answer
The user left the screen before the Future completed, so the widget was unmounted. Before using context or calling setState after await, check if (!context.mounted) return; or if (!mounted) return; in State. Better still, move async logic out of widgets into a state management layer that the UI listens to, and cancel subscriptions or timers in dispose so no callbacks run on a dead widget.
20

Parsing a 10 MB JSON file freezes the Flutter UI for two seconds. How do you fix it?

Save to ▾
Show answer
JSON decoding is CPU-bound and runs on the main isolate, blocking frames. Move it to a background isolate with Isolate.run(() => parseProducts(jsonString)) or compute. Also consider whether the API can paginate or return less data, and parse lazily. Test in profile mode with DevTools performance view to confirm the frame time improvement, since debug mode exaggerates slowness.
21

How do you create reusable custom widgets in Flutter?

Save to ▾
Show answer
Extract repeated UI into a StatelessWidget class with clear constructor parameters, rather than helper methods that return widgets, because classes get their own element, can be const and rebuild independently. Accept callbacks for events, use the theme for colours and text styles, and provide sensible defaults. Group them into a shared widgets folder or design system package and document them with widget previews or a showcase screen.
22

How do you implement a form with validation in Flutter?

Save to ▾
Show answer
Wrap fields in a Form with a GlobalKey<FormState>, use TextFormField with a validator function that returns an error string or null, and call formKey.currentState!.validate() on submit. Use TextEditingController for values and dispose it, set keyboardType and textInputAction for each field, and autovalidateMode onUserInteraction to show errors as the user types. Keep validation rules in testable functions outside widgets.
23

Explain the three trees in Flutter: widget, element and render object.

Save to ▾
Show answer
Widgets are lightweight, immutable descriptions of UI created on every build. Elements are the mounted instances that hold a widget's position in the tree and link to State; they are reused when a new widget of the same type and key appears. RenderObjects handle layout, painting and hit testing, and are expensive, so Flutter updates them only when needed. This design makes frequent rebuilds cheap.
24

What are records and patterns in Dart 3?

Save to ▾
Show answer
Records are anonymous, immutable aggregates like (String, int) or ({String name, int age}), useful for returning multiple values without creating a class. Patterns let you destructure values and match shapes in switch expressions and if-case statements. Combined with sealed classes, switch can be exhaustive, so the compiler warns when a case is missing. They make state handling and parsing code shorter and safer.
25

How does Flutter's layout rule of constraints go down, sizes go up work?

Save to ▾
Show answer
A parent passes constraints, minimum and maximum width and height, to each child. The child chooses its size within those constraints and reports it up, then the parent positions the child. A widget cannot choose a size outside its constraints, which explains why a Container with width 100 may still fill the screen if forced by tight constraints. Understanding this rule solves most overflow and unbounded constraint errors.

Frequently asked questions

How important is Dart and Flutter Basics in Mobile App Development interviews?

Flutter uses Dart and a widget-based UI rendered by its own engine. Learn null safety, async-await, streams, isolates, records and patterns, stateless and stateful widgets, the widget lifecycle, keys, layouts and forms. Expect live coding tasks such as building a list screen and questions on how Flutter's layout and rendering pipeline work.

How should I use the Dart and Flutter Basics sheet?

Go top to bottom — easy to hard. Answer before opening each answer, tick what you solved and save misses to Last-Minute Revision.