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
isolateInterview 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
ListTileInterview 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 stateInterview 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.keypasses 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 loadingExample:
@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
InheritedWidgetInterview 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 subscriptionsExample:
@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:
finalmakes 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 type22. fromJson()
Converts JSON map into Dart object.
final user = UserModel.fromJson(json);Flow:
API JSON → fromJson() → Dart Model Object → UIAPI 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:
awaitwaits 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.headers28. Status Code
Common status codes:
200 = Success
201 = Created
400 = Bad Request
401 = Unauthorized
403 = Forbidden
404 = Not Found
500 = Server Error29. 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 object31. .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.error34. 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.builderlazily 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 eventRouting 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 andpop()removes the current screen.
41. Navigation Stack
Example:
UserDetailScreen ← current
UserListScreenWhen pop() is called:
UserListScreen ← current42. 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 constructorNamed Routes Glossary
46. Named Routes
Named routes allow navigation using route names.
Navigator.pushNamed(context, '/user-detail');Example route names:
/
/login
/home
/user-detail47. 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:
onGenerateRouteis 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: userReceive it using:
final user = settings.arguments as UserModel;Memory trick:
Navigator.push() → constructor
Navigator.pushNamed() → argumentsArchitecture Glossary
53. Flutter Project Architecture
For production apps, use Clean Architecture:
Presentation Layer
Domain Layer
Data Layer54. Presentation Layer
Contains:
Screens/pages
Widgets
Bloc / Cubit / Provider / Riverpod
UI states
User actionsResponsibility:
UI and state management.
55. Domain Layer
Contains:
Entities
Use cases
Repository interfaces
Business logicResponsibility:
Pure business logic, independent of UI and API details.
56. Data Layer
Contains:
Models
API calls
Local database
Remote data source
Repository implementation
Secure storageResponsibility:
Data fetching and data conversion.
57. Clean Architecture Flow
UI Page
↓
Bloc / Provider / Riverpod
↓
UseCase
↓
Repository Interface
↓
Repository Implementation
↓
Remote Data Source
↓
APIPlatform-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-CInterview 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 infoInterview line:
MethodChannel is used for one-time native method calls.
60. EventChannel
Used for continuous data streams.
Example:
Location updates
Bluetooth status
Sensor updatesInterview 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 SDK62. iOS Native Side
For iOS platform channel, use:
Swift / Objective-C
AppDelegate.swift
Info.plist
Xcode
CocoaPodsFlutter Setup Glossary
63. IDE
Common IDEs:
Android Studio
VS Code
Xcode for iOS64. Android Studio Flutter Plugin
Required plugin:
Flutter plugin
Dart pluginUsed for:
Flutter project creation
Run/debug
Hot reload
Widget inspector
Dart support65. Flutter SDK Path
In Android Studio, configure Flutter SDK path.
Example:
C:\Users\hp\develop\flutterDo not select:
C:\Users\hp\develop\flutter\bin66. flutter doctor
Checks Flutter setup.
flutter doctorUsed to check:
Flutter SDK
Android SDK
Licenses
Emulator
Connected device
Xcode on MacDependency 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
Riverpod69. 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 service71. registerFactory
Creates new object every time.
Good for:
Bloc
Cubit
ViewModelMost 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 usingargumentsand receive it fromRouteSettings.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