Flutter Interview Revision Glossary

1. Flutter

Flutter is Google’s cross-platform UI framework used to build Android, iOS, web, and desktop apps from a single codebase.

Interview line:

Flutter allows us to build cross-platform apps using Dart. It provides its own rendering engine and widget-based UI system.


2. Dart

Dart is the programming language used by Flutter.

Important Dart concepts:

final
const
var
dynamic
null safety
Future
async/await
Stream
factory constructor
mixin
extension
isolate

Interview line:

Dart is an object-oriented language optimized for UI development. It supports null safety, async-await, Futures, Streams, and AOT/JIT compilation.


3. Widget

In Flutter, everything is a widget.

Examples:

Text
Container
Row
Column
Scaffold
AppBar
ListView
Card
ListTile

Interview line:

A widget describes how the UI should look.


4. StatelessWidget

Used when UI does not change internally.

Example:

class MyText extends StatelessWidget {
const MyText({super.key});

@override
Widget build(BuildContext context) {
return const Text("Hello");
}
}

Interview line:

StatelessWidget is used when the widget does not manage mutable state.


5. StatefulWidget

Used when UI changes based on state.

Example use cases:

API loading
Form input
Counter
Selected item
Login state

Interview line:

StatefulWidget is used when the UI needs to rebuild based on changing data.


6. super.key

const UserListScreen({super.key});

super.key passes the widget key to the parent widget class.

Older syntax:

const UserListScreen({Key? key}) : super(key: key);

Interview line:

super.key passes the widget key to the parent class. A key helps Flutter identify widgets during rebuilds.


7. createState()

@override
State<UserListScreen> createState() => _UserListScreenState();

This creates the State object for a StatefulWidget.

Interview line:

createState() connects the StatefulWidget with its mutable State class.


8. StatefulWidget Lifecycle

Correct lifecycle flow:

createState()

initState()

didChangeDependencies()

build()

setState() → build()

didUpdateWidget() → build()

deactivate()

dispose()

Creation phase

createState()
initState()
didChangeDependencies()
build()

Alive/update phase

setState() → build()
didUpdateWidget() → build()
didChangeDependencies() → build()

Removal phase

deactivate()
dispose()

9. initState()

Called only once when the State object is created.

Used for:

API call
Controller initialization
Listener setup
Initial data loading

Example:

@override
void initState() {
super.initState();
usersFuture = userService.fetchUsers();
}

Interview line:

initState() is used for one-time initialization before the first build.


10. build()

build() creates the UI.

@override
Widget build(BuildContext context) {
return Scaffold(
body: Text("Hello"),
);
}

Important point:

Do not call API directly inside build() because build can run multiple times.


11. setState()

Used to update state and rebuild UI.

setState(() {
count++;
});

Interview line:

setState() tells Flutter that state has changed and the widget should rebuild.


12. didChangeDependencies()

Called after initState() and when inherited dependencies change.

Examples:

Theme
MediaQuery
Localizations
Provider
InheritedWidget

Interview line:

didChangeDependencies() is called when context-based inherited dependencies change.


13. didUpdateWidget()

Called when parent passes new values to the same widget.

Example:

@override
void didUpdateWidget(covariant UserDetailScreen oldWidget) {
super.didUpdateWidget(oldWidget);

if (oldWidget.userId != widget.userId) {
// reload data
}
}

Interview line:

didUpdateWidget() is used to compare old and new widget properties when the parent updates the widget configuration.


14. deactivate()

Called when widget is removed temporarily from the widget tree.

Interview line:

deactivate() is called when the State object is removed from the tree, but it may be inserted again.


15. dispose()

Called when widget is permanently removed.

Used for cleanup:

Dispose controllers
Cancel timers
Cancel streams
Remove listeners
Close subscriptions

Example:

@override
void dispose() {
controller.dispose();
super.dispose();
}

Interview line:

dispose() is used to clean up resources and prevent memory leaks.


Dart Model and API Glossary

16. Model Class

A model class represents API data as a Dart object.

Example:

class UserModel {
final int id;
final String name;
final String email;

UserModel({
required this.id,
required this.name,
required this.email,
});
}

Interview line:

A model class converts raw JSON into strongly typed Dart objects.


17. final

final String name;

final means value can be assigned only once.

Interview line:

final makes the property immutable after assignment.


18. Constructor

Used to create an object.

UserModel({
required this.id,
required this.name,
});

Example:

final user = UserModel(
id: 1,
name: "Himanshu",
);

19. required

Means the parameter must be passed.

UserModel({
required this.id,
required this.name,
});

Without required values, object creation gives compile-time error.


20. Factory Constructor

Used for custom object creation logic.

factory UserModel.fromJson(Map<String, dynamic> json) {
return UserModel(
id: json['id'],
name: json['name'],
);
}

Interview line:

Factory constructors are commonly used to convert JSON into Dart model objects.


21. Map<String, dynamic>

Represents JSON-like key-value data.

{
"id": 1,
"name": "Himanshu"
}

Meaning:

String = key type
dynamic = value can be any type

22. fromJson()

Converts JSON map into Dart object.

final user = UserModel.fromJson(json);

Flow:

API JSON → fromJson() → Dart Model Object → UI

API Integration Glossary

23. Future

A Future represents a value that will come later.

Future<List<UserModel>> fetchUsers() async {
// API call
}

Interview line:

Future is used for async operations that return one value later, like API calls.


24. async

Marks a function as asynchronous.

Future<void> loadData() async {
}

25. await

Waits for async operation to complete.

final response = await http.get(url);

Interview line:

await waits for the async result without blocking the UI thread.


26. Uri.parse()

Converts string URL into URI object.

final url = Uri.parse('https://jsonplaceholder.typicode.com/users');

27. http.get()

Sends GET request to API.

final response = await http.get(url);

Response contains:

response.statusCode
response.body
response.headers

28. Status Code

Common status codes:

200 = Success
201 = Created
400 = Bad Request
401 = Unauthorized
403 = Forbidden
404 = Not Found
500 = Server Error

29. jsonDecode()

Converts JSON string into Dart object.

final jsonData = jsonDecode(response.body);

30. .map()

Transforms each item in a list.

jsonData.map((json) => UserModel.fromJson(json))

Meaning:

JSON object → UserModel object

31. .toList()

Converts iterable result into List.

jsonData
.map((json) => UserModel.fromJson(json))
.toList();

FutureBuilder Glossary

32. FutureBuilder

FutureBuilder builds UI based on Future state.

FutureBuilder<List<UserModel>>(
future: usersFuture,
builder: (context, snapshot) {
// UI here
},
)

Interview line:

FutureBuilder listens to a Future and rebuilds UI for loading, error, empty, or success state.


33. Snapshot

snapshot contains current Future state.

Important properties:

snapshot.connectionState
snapshot.hasData
snapshot.data
snapshot.hasError
snapshot.error

34. Loading State

if (snapshot.connectionState == ConnectionState.waiting) {
return const CircularProgressIndicator();
}

35. Error State

if (snapshot.hasError) {
return Text('Error: ${snapshot.error}');
}

36. Empty State

if (!snapshot.hasData || snapshot.data!.isEmpty) {
return const Text('No users found');
}

37. Success State

final users = snapshot.data!;

Then show data using ListView.builder.


38. ListView.builder

Used to show dynamic lists efficiently.

ListView.builder(
itemCount: users.length,
itemBuilder: (context, index) {
final user = users[index];
return Text(user.name);
},
);

Interview line:

ListView.builder lazily builds list items and is better for large or dynamic lists.


39. ListTile

Ready-made row layout.

ListTile(
leading: CircleAvatar(),
title: Text(user.name),
subtitle: Text(user.email),
trailing: Icon(Icons.arrow_forward_ios),
)

Parts:

leading = left widget
title = main text
subtitle = secondary text
trailing = right widget
onTap = click event

Routing Glossary

40. Navigator

Navigator is used to move between screens.

Navigator.push(
context,
MaterialPageRoute(
builder: (context) => UserDetailScreen(user: user),
),
);

Interview line:

Navigator manages screens using a stack. push() adds a screen and pop() removes the current screen.


41. Navigation Stack

Example:

UserDetailScreen  ← current
UserListScreen

When pop() is called:

UserListScreen ← current

42. Navigator.push()

Opens a new screen.

Navigator.push(
context,
MaterialPageRoute(
builder: (_) => UserDetailScreen(user: user),
),
);

Data is passed using constructor.


43. Navigator.pop()

Goes back to previous screen.

Navigator.pop(context);

44. MaterialPageRoute

Creates a route/page transition.

MaterialPageRoute(
builder: (context) => UserDetailScreen(user: user),
)

45. Passing Data by Constructor

Used with direct navigation.

UserDetailScreen(user: user)

Memory trick:

Navigator.push() → pass data using constructor

Named Routes Glossary

46. Named Routes

Named routes allow navigation using route names.

Navigator.pushNamed(context, '/user-detail');

Example route names:

/
/login
/home
/user-detail

47. Route Constants

Used to avoid spelling mistakes.

class AppRoutes {
static const String userList = '/';
static const String userDetail = '/user-detail';
}

48. initialRoute

Defines first screen.

initialRoute: AppRoutes.userList,

49. routes

Used for simple static routes.

routes: {
AppRoutes.userList: (context) => const UserListScreen(),
},

50. onGenerateRoute

Used for dynamic routing and arguments.

onGenerateRoute: (settings) {
if (settings.name == AppRoutes.userDetail) {
final user = settings.arguments as UserModel;

return MaterialPageRoute(
builder: (context) => UserDetailScreen(user: user),
);
}

return null;
}

Interview line:

onGenerateRoute is useful when we need dynamic routing, custom route handling, or passing arguments.


51. Navigator.pushNamed()

Used to open named route.

Navigator.pushNamed(
context,
AppRoutes.userDetail,
arguments: user,
);

52. arguments

Used to pass data with named routes.

arguments: user

Receive it using:

final user = settings.arguments as UserModel;

Memory trick:

Navigator.push() → constructor
Navigator.pushNamed() → arguments

Architecture Glossary

53. Flutter Project Architecture

For production apps, use Clean Architecture:

Presentation Layer
Domain Layer
Data Layer

54. Presentation Layer

Contains:

Screens/pages
Widgets
Bloc / Cubit / Provider / Riverpod
UI states
User actions

Responsibility:

UI and state management.


55. Domain Layer

Contains:

Entities
Use cases
Repository interfaces
Business logic

Responsibility:

Pure business logic, independent of UI and API details.


56. Data Layer

Contains:

Models
API calls
Local database
Remote data source
Repository implementation
Secure storage

Responsibility:

Data fetching and data conversion.


57. Clean Architecture Flow

UI Page

Bloc / Provider / Riverpod

UseCase

Repository Interface

Repository Implementation

Remote Data Source

API

Platform-Specific Glossary

58. Platform Channels

Used when Flutter needs to call native Android/iOS code.

Flutter Dart

Platform Channel

Android Kotlin/Java
iOS Swift/Objective-C

Interview line:

If no Flutter plugin exists, we use Platform Channels to call native Android or iOS code.


59. MethodChannel

Used for request-response communication.

Example:

Get battery level
Start payment
Get device info

Interview line:

MethodChannel is used for one-time native method calls.


60. EventChannel

Used for continuous data streams.

Example:

Location updates
Bluetooth status
Sensor updates

Interview line:

EventChannel is used when native side sends continuous events to Flutter.


61. Android Native Side

For Android platform channel, use:

Kotlin / Java
MainActivity.kt
Android SDK

62. iOS Native Side

For iOS platform channel, use:

Swift / Objective-C
AppDelegate.swift
Info.plist
Xcode
CocoaPods

Flutter Setup Glossary

63. IDE

Common IDEs:

Android Studio
VS Code
Xcode for iOS

64. Android Studio Flutter Plugin

Required plugin:

Flutter plugin
Dart plugin

Used for:

Flutter project creation
Run/debug
Hot reload
Widget inspector
Dart support

65. Flutter SDK Path

In Android Studio, configure Flutter SDK path.

Example:

C:\Users\hp\develop\flutter

Do not select:

C:\Users\hp\develop\flutter\bin

66. flutter doctor

Checks Flutter setup.

flutter doctor

Used to check:

Flutter SDK
Android SDK
Licenses
Emulator
Connected device
Xcode on Mac

Dependency Injection Glossary

67. Dependency Injection

Means providing dependencies from outside instead of creating them inside a class.

Bad:

class LoginUseCase {
final repository = AuthRepositoryImpl();
}

Good:

class LoginUseCase {
final AuthRepository repository;

LoginUseCase(this.repository);
}

Interview line:

Dependency Injection improves testability, loose coupling, and maintainability.


68. Common DI Packages

get_it
injectable
Provider
Riverpod

69. get_it

Service locator package.

final sl = GetIt.instance;

Register dependency:

sl.registerLazySingleton<AuthRepository>(
() => AuthRepositoryImpl(),
);

Use dependency:

final repo = sl<AuthRepository>();

70. registerLazySingleton

Creates object once and reuses same instance.

Good for:

API client
Repository
Storage service
Network service

71. registerFactory

Creates new object every time.

Good for:

Bloc
Cubit
ViewModel

Most Important Interview Answers

What is BuildContext?

BuildContext represents the location of a widget in the widget tree. It helps access parent widgets and inherited services like Theme, MediaQuery, Navigator, Provider, and Bloc.

Why not call API in build?

Because build() can execute many times. Calling API inside build can trigger repeated network calls.

How does Flutter interact with Android/iOS native code?

Flutter uses Platform Channels. For one-time calls we use MethodChannel, and for continuous events we use EventChannel.

How do named routes pass data?

With Navigator.pushNamed(), we pass data using arguments and receive it from RouteSettings.arguments.

What architecture do you use in Flutter?

I prefer Clean Architecture with Presentation, Domain, and Data layers.

How do you perform dependency injection?

We can use constructor injection, get_it, injectable, Provider, or Riverpod. In Clean Architecture, get_it with injectable is commonly used.


Final Revision Memory Map

Flutter
├── Dart basics
├── Widgets
│ ├── StatelessWidget
│ └── StatefulWidget
├── Lifecycle
│ ├── initState
│ ├── build
│ ├── didChangeDependencies
│ ├── didUpdateWidget
│ └── dispose
├── API
│ ├── Future
│ ├── async/await
│ ├── jsonDecode
│ └── fromJson
├── UI Binding
│ ├── FutureBuilder
│ ├── snapshot
│ └── ListView.builder
├── Routing
│ ├── Navigator.push
│ ├── Navigator.pop
│ ├── pushNamed
│ └── arguments
├── Architecture
│ ├── Presentation
│ ├── Domain
│ └── Data
├── Native Integration
│ ├── Platform Channel
│ ├── MethodChannel
│ └── EventChannel
└── DI
├── get_it
├── injectable
└── Riverpod

Leave a Comment

Your email address will not be published. Required fields are marked *