All 75 Flutter quiz questions below come with a short explanation, visible right on the page — no sign-in needed. They're grouped by beginner and intermediate levels and 74 subtopics, so you can revise one part at a time. Choose Try Flutter quiz above to take a scored run and review the questions you got wrong.
When must you use a StatefulWidget instead of a StatelessWidget?
A.When the widget takes any parameter from its parent
B.When the widget sits more than three levels deep in the tree
C.When the widget must fetch data from an API over the network
D.When the widget must hold data that changes between builds
Answer: D
Use a StatefulWidget when the widget needs to hold data that changes over time and trigger rebuilds itself, e.g. input, counters, loading state. If everything displayed comes from passed-in parameters, a StatelessWidget is enough and cheaper.
D.The current state of the widget and its children
Answer: C
BuildContext is a handle to a widget's position in the element tree. From there Flutter looks upward to find the nearest ancestor widget, which is why Theme.of(context) and Navigator.of(context) work. The wrong context is the wrong starting point for the lookup.
What happens if you assign a new value to a state field without calling setState?
A.The value reverts to its default on the next build
B.Flutter throws an error right at the assignment
C.The value changes but the interface is not redrawn
D.The interface still updates, just one frame later
Answer: C
The value really changes but the screen doesn't repaint. setState doesn't assign data; it only marks the element dirty so Flutter schedules a rebuild on the next frame. That's also why the screen still looks correct when some other widget accidentally triggers a rebuild.
You change the initial value of a State field but hot reload shows no difference. Why?
A.Hot reload keeps the old state and only reloads the code
B.Hot reload ignores every change inside a State class
C.The file must be saved again for the compiler to notice
D.The initialized variable must be declared late to be reloaded
Answer: A
Hot reload loads new code but keeps the running state, so initState and initial values don't run again. To see this kind of change use hot restart: it rebuilds the whole app from scratch, losing state but still faster than a full rebuild.
What does putting const before a widget constructor buy you?
A.The widget is locked so the parent cannot pass new parameters
B.The widget is compressed so the installed package is smaller
C.The widget is reused so that branch skips the rebuild
D.The widget is drawn on a separate thread so it is smoother
Answer: C
const creates a single object reused many times. On rebuild, Flutter sees the new widget is identical to the old one and skips that whole subtree. It's the cheapest optimization in Flutter and also the most commonly missed one.
A Column with content taller than the screen reports an overflow. What is the correct fix?
A.Set mainAxisSize to MainAxisSize.min
B.Wrap the Column in Expanded so it shrinks itself
C.Reduce the font size until it fits the screen
D.Wrap it in a SingleChildScrollView so it can scroll
Answer: D
Wrap it in a SingleChildScrollView so long content becomes a scrollable area. For lists with many items use ListView so only the visible part is built. Shrinking font size or cutting content only works around the problem on the exact device being tested.
How do Navigator.push and Navigator.pushReplacement differ?
A.pushReplacement removes the current screen from the stack
B.pushReplacement clears every screen from the stack
C.push opens a new screen while pushReplacement opens a dialog
D.pushReplacement runs no screen transition animation
Answer: A
push stacks a new screen on top, while pushReplacementreplaces the current screen so it disappears from the stack. Use it for splash or login screens, where the user shouldn't be able to go back with the back button.
B.The value directly, with Dart awaiting it at the call site
C.A Future that completes after the body has run
D.An Isolate running in parallel with the main thread
Answer: C
An async function always returns a Future. Dart wraps the return value in a Future even when the function body has no await. Forgetting await at the call site is the number one reason a variable prints as Instance of Future.
A.It asserts the value is not null and throws if it is
B.It converts a nullable variable to non-nullable permanently
C.It skips the method call if the value is null
D.It assigns a default value when the expression is null
Answer: A
The ! operator is an assertion that the value is not null. The compiler trusts it and lets it through, but at runtime if the value is null it throws immediately. Using lots of ! is a sign the data model isn't tight, not a way to handle null.
What is the difference between dependencies and dev_dependencies in pubspec.yaml?
A.dev_dependencies only work on an emulator rather than a real device
B.dependencies are version-locked while dev ones are not
C.dev_dependencies do not go into the released package
D.dev_dependencies only accept packages written in-house
Answer: C
dev_dependencies are used only during development, such as flutter_test, build_runner, mocktail, so they are not packaged into the release. dependencies are what the app needs at runtime, so they directly affect install size.
For a fixed empty gap, should you use SizedBox or Container?
A.Container, because SizedBox requires a child widget
B.Both are wrong; use Padding for a gap
C.Container, because it handles the gap more precisely
D.SizedBox, because it is lighter and can be built as const
Answer: D
SizedBox for a pure gap, because it only applies a size constraint and can be built with const. Container is a convenience widget that bundles padding, color, border, and transform, so it is only worth using when you actually need two or more of those.
An image added to the assets folder is not found at runtime. What step is missing?
A.Declare the path under the assets section of pubspec.yaml
B.Convert the image to webp so Flutter can read it
C.Rename the file without diacritics or spaces
D.Run flutter clean and rebuild from scratch
Answer: A
It must be declared in pubspec.yaml under assets. Declaring a whole directory with a path ending in a slash also works, but it only applies to files directly in that directory and does not recurse into subdirectories.
A.A ready-made layout frame for the app bar, body, drawer and snack bar
B.A router managing the application's screen stack
C.The colour and typography theme for the whole application
D.An automatic safe area avoiding the notch on every device
Answer: A
Scaffold is the frame of a Material screen: appBar, body, drawer, bottomNavigationBar, floatingActionButton, and the place where snack bars show. It handles stacking and reserving space among those regions so you do not have to compute coordinates yourself.
A.Persisting the field's value on the device between sessions
B.Reading and setting the input field's content from outside
C.Dismissing the keyboard when the user presses confirm
D.Validating what the user typed
Answer: B
TextEditingController holds the content and cursor position of a TextField, letting you read, reset the value, and listen for changes from outside the widget. It must be disposed in State, otherwise it leaks memory.
Image.network refetches on every screen open. What is the appropriate fix?
A.Fetch the image with http and draw it with Image.memory
B.Wrap the image widget in const to keep the old object
C.Raise Flutter's image cache size to its maximum
D.Use a package that caches images to disk such as cached_network_image
Answer: D
Flutter's default image cache lives only in RAM and disappears when the app closes. To persist across sessions you need disk caching, most commonly cached_network_image, which also provides placeholder and error images.
C.InkWell needs no child widget while GestureDetector does
D.InkWell paints the Material ripple effect
Answer: D
InkWell captures touch gestures with a Material ripple effect, while GestureDetector only detects gestures without drawing anything. In return, GestureDetector covers more gesture types such as drag, swipe, scale, and double-tap.
How do you create spacing outside a widget border in Flutter?
A.Set the margin property on that widget
B.Wrap that widget in a Padding at the outer level
C.Set the offset property inside the widget's decoration
D.Use Transform.translate to move the widget away
Answer: B
Flutter doesn't separate margin and padding like CSS. Outer spacing is just padding on the wrapping widget, usually written with Padding or a SizedBox between elements. Container has margin only because it wraps itself in an extra outer Padding.
Why must WidgetsFlutterBinding.ensureInitialized be called before runApp in some cases?
A.Because runApp can only run once the interface has been built
B.Because Dart must know how many widgets the application has
C.Because the screen orientation must be locked before the first frame
D.Because plugins need the platform channel ready before being called
Answer: D
Calling any plugin before runApp requires the platform channel to be ready, and that channel only exists after the binding is initialized. That's why initializing Firebase, reading shared_preferences, or locking screen orientation in main all require this line.
B.const needs a compile-time known value while final does not
C.final forbids reassignment while const still allows it
D.final only works inside a function rather than for a class field
Answer: B
Both forbid reassignment. The difference is timing: const needs a compile-time constant, so the object is shared and deeply frozen, while final allows a runtime value, e.g. final now = DateTime.now().
What risk comes from declaring a variable dynamic instead of var?
A.The variable uses considerably more memory than with var
B.The variable cannot be reassigned after the first initialization
C.It loses type checking so errors only surface at runtime
D.The compiler refuses to build in release mode
Answer: C
var is type inference; the variable still has a fixed static type after its first assignment. dynamicdisables type checking, deferring every method call to runtime, so a mistyped function name only crashes when the user hits that exact branch.
Flutter keeps three parallel trees. What is the element tree for?
A.It stores the drawn image so the next frame can reuse it
B.It holds the immutable description of the desired interface
C.It holds the state and links the widget to the render object
D.It computes sizes and positions during layout
Answer: C
The element tree is the long-lived middle layer: widgets are immutable descriptions thrown away continuously, render objects handle measuring and painting, while elements hold position, hold State, and decide whether this rebuild should reuse or create a new render object.
After removing one item from a list of StatefulWidgets, state ends up on the wrong item. Why?
A.Because ListView reuses widgets like Android's RecyclerView
B.Because the items are not wrapped in RepaintBoundary
C.Because setState was called before the list finished updating
D.Missing keys, so Flutter matches widgets by position
Answer: D
Missing key. When matching new widgets to old elements, Flutter compares by type and position, so deleting a middle list item shifts later items up and they pick up the wrong old State. Add a ValueKey based on the data id.
A.Constraints go down, sizes come up, the parent sets the position
B.Every widget takes its size from the screen's MediaQuery
C.The child picks its size and the parent must stretch to fit
D.Sizes are computed in two passes as in CSS flexbox
Answer: A
Constraints go down, sizes go up, parent sets position. The parent passes down allowed width and height constraints, the child picks its size within them and reports back, then the parent decides where to place the child. Most layout bugs come from misunderstanding one of these three steps.
A 5000-row list built with ListView children janks badly. Why?
A.Each row creates its own RepaintBoundary, wasting memory
B.All 5000 widgets are built at once
C.ListView repaints the whole list on every scroll frame
D.Missing keys force Flutter to rebuild the subtree each time
Answer: B
The ListView(children: [...]) form builds all items up front before display. With 5000 rows that is 5000 widgets at once. ListView.builder only builds what is visible plus a buffer, so the cost no longer depends on list length.
A.Type reflection to find a parent widget of the matching type
B.An InheritedWidget allows an upward lookup and registers the dependency
C.An event bus broadcasting events down to every child widget
D.A global singleton MaterialApp creates at runtime
Answer: B
Theme.of(context) is an InheritedWidget. The call both finds the nearest ancestor widget of that type and registers a dependency, so when the theme changes only the widgets that read it are rebuilt, not the whole tree.
A screen using AnimationController and ScrollController leaks memory. What step is missing?
A.Calling setState one last time before leaving the screen
B.Calling dispose on the controllers in the State
C.Wrapping the screen in AutomaticKeepAliveClientMixin
D.Declaring the controllers late final rather than final
Answer: B
Missing dispose(). Controllers, StreamSubscription, FocusNode, TextEditingController all hold references and listeners; if not disposed they stay alive after the screen closes, keeping the old widget tree in memory too.
Two widgets listen to the same Stream and the second one throws. Why?
A.Because StreamBuilder automatically cancels the previous widget's subscription
B.Because each widget needs its own BuildContext to listen
C.Because the stream finished emitting before the second widget attached
D.A single-subscription stream only allows one listener
Answer: D
A Stream is single-subscription by default, accepting only one listener for its lifetime. A second listen throws immediately. Use asBroadcastStream(), a StreamController.broadcast, or better, have a repository layer hold the data and re-emit it to widgets.
A FutureBuilder refetches on every parent rebuild. What is the correct fix?
A.Wrap the FutureBuilder in a const widget to block rebuilds
B.Create the Future once in initState and pass it in
C.Check snapshot.connectionState and return early
D.Set initialData so FutureBuilder skips the later call
Answer: B
The cause is creating the Future inside build: every rebuild produces a new Future, so FutureBuilder runs again from scratch. Create it once in initState and store it in a State field, or let an external state-management class hold the result.
D.Provider is synchronous while Riverpod is asynchronous
Answer: B
Riverpod does not look up through BuildContext. Provider finds data by walking up the widget tree, so placing it wrong throws at runtime, whereas Riverpod providers are global variables with explicit types, so mistakes surface earlier.
Decoding a 5 MB JSON on the UI thread freezes the app. What is the right fix?
A.Mark the decoding function async and await the result
B.Move the decoding to an isolate with compute
C.Wrap the display in a RepaintBoundary to reduce repainting
D.Split the data across several smaller setState calls
Answer: B
Move the heavy computation to an isolate, the simplest being compute(jsonDecode, raw). An isolate has its own memory and event loop, so the UI thread stays free to hold 60 frames. async does not help because it does not create a new thread.
When should you use an AnimationController instead of an AnimatedContainer?
A.When the widget must animate several properties at once
B.When the app must run smoothly on low-end devices
C.When you need to control the progress, repeat, or reverse it
D.When the animation must run longer than 300 milliseconds
Answer: C
Use AnimationController when you need control: pause, reverse, repeat, orchestrate multiple animations along a timeline, or tie progress to a drag gesture. Implicit animations like AnimatedContainer are only suited to one-way state transitions.
A.Flexible enables scrolling while Expanded does not
B.Expanded works by percentage while Flexible works in pixels
C.Expanded forces the child to fill the spare space while Flexible does not
D.Expanded is only for Row and Flexible only for Column
Answer: C
Expanded is Flexible with fit: FlexFit.tight, so the child must fill its allocated share. Flexible defaults to loose, so the child may be smaller. Both distribute the leftover space by the flex factor.
When should LayoutBuilder be preferred over MediaQuery?
A.When you need the status bar height and the safe area
B.When you need to know whether the device is landscape or portrait
C.When you need the system font size the user has set
D.When you need the size of the widget's own container
Answer: D
Use LayoutBuilder when the decision depends on the size of the widget's container, such as a card in a grid or a pane in a split screen. MediaQuery describes the whole screen, so it is still right for safe area, orientation, and system text scale.
Why can Flutter not convert JSON into objects automatically like some other frameworks?
A.Flutter lacks runtime reflection for JSON mapping
B.Because Dart's standard library does not support JSON decoding
C.Because Dart has no Map type to represent JSON
D.Because Flutter blocks reflection to reduce security risk
Answer: A
Flutter does not support runtime reflection to map JSON to models automatically. In release, the app is compiled AOT and tree shaking makes reflection-based models even less suitable. So you must write fromJson by hand or generate code with json_serializable and freezed via build_runner.
What is the right way to switch the API endpoint between dev and production?
A.Set a global flag and edit it by hand before each release
B.Read an operating system environment variable at startup
C.Use kDebugMode to pick the corresponding endpoint
D.Pass it via dart-define combined with a build flavor
Answer: D
Use --dart-define or --dart-define-from-file to pin configuration at build time, combined with flavors when the package name, icon, and services also differ. That way dev and production builds can be installed side by side on the same machine.
What is the right way for one screen to use a different colour scheme from the rest of the app?
A.Set a global colour variable and read it in the widget's build
B.Pass the colours as parameters down to each child widget
C.Change MaterialApp's ThemeData when that screen opens
D.Wrap that screen in a Theme with its own theme data
Answer: D
Wrap that branch with Theme and pass a separate ThemeData, usually derived from the current theme via copyWith. Because Theme is an InheritedWidget, every widget below reads the nearest value while the rest of the app stays unchanged.
When should you use a mixin instead of extending an abstract class in Dart?
A.When you need to share behaviour across classes with different parents
B.When you need subclasses to reimplement every method
C.When you need to declare a mutable field
D.When you need to instantiate it directly without a subclass
Answer: A
Use a mixin when you need to share behavior horizontally across classes that don't share an inheritance tree. Dart allows extending only one class but mixing in many mixins, so mixins suit pieces like logging, data validation, or managing a shared resource.
What is the main benefit of a Dart 3 sealed class when modelling state?
A.It provides value equality without writing anything extra
B.The subclasses become immutable automatically
C.The compiler catches a switch that misses a branch
D.It reduces the package size by eliminating dead code
Answer: C
sealed locks the set of subclasses within the same file, making switch an exhaustiveness check at compile time. Adding a new state and forgetting to handle it somewhere breaks the build immediately, instead of surfacing when a user hits a blank screen.
How does a MethodChannel move data between Dart and native code?
A.Asynchronously encoded messages over a shared channel name
B.Generating bridge code at build time from an interface declaration
C.Calling the native function directly and synchronously in the same process
D.Running the native code in its own Dart isolate
Answer: A
MethodChannel is an asynchronous message bus keyed by channel name. Dart sends a method name with arguments, the data is binary-encoded, the native side handles it and returns a result. Because matching is by string, a mistyped name only shows up at runtime.
What is the problem with storing an auth token in shared_preferences?
A.The data is wiped every time the application updates
B.The data is unencrypted so a rooted device can read it
C.The reads and writes are synchronous so they freeze the interface
D.The maximum storage size is too small for a token
Answer: B
shared_preferences writes to the platform's regular config file and is not encrypted at all. On a rooted or jailbroken device, the contents are easily read. Tokens, keys, and personal data should live in flutter_secure_storage to use Keystore and Keychain.
An app needs offline reads with complex filtering and sorting. Which option fits?
A.Keep it in the HTTP cache and read it back when offline
B.Write everything to a JSON file and filter it in memory
C.A SQLite database through sqflite or drift
D.Save it to shared_preferences as a JSON-encoded string
Answer: C
For relational data that needs filtering and sorting, use SQLite via sqflite, or drift when you want typed queries and clear migrations. A key-value store only fits when you always read by key and the data volume is small.
What is the tidiest way to refresh an access token when the API returns 401?
A.Set a timer to refresh the token periodically by its expiry
B.Catch the exception at the interface layer and ask the user to log in again
C.Put an interceptor at the HTTP client layer to retry once
D.Check the status code in every API-calling function and handle it there
Answer: C
Use an interceptor at the client layer, e.g. Dio: catch the 401 response, call the token refresh, then replay that exact request once. You must lock it so multiple parallel requests trigger only one refresh, otherwise you get overlapping refresh chains.
How does a widget test differ from an integration test?
A.A widget test runs without a device so it is much faster
B.A widget test can only test stateless widgets
C.A widget test requires a golden image to compare against
D.An integration test cannot call a real API
Answer: A
A widget test builds the widget tree in an in-memory test environment, needs no device, and runs in milliseconds. An integration test runs the whole app on a device or emulator, closer to reality but much slower and far more flaky.
Which build mode should be used to measure Flutter performance?
A.Profile, because it compiles like release but keeps the measurement tools
B.Release, because that is what users run
C.Any mode, since the results are equivalent
D.Debug, because it has the fullest debugging information
Answer: A
Use profile. Debug mode runs the Dart VM with JIT compilation and extra checks, so it is many times slower than reality. Profile compiles ahead of time like release but keeps enough tooling to view frame charts in DevTools.
What is the most effective way to reduce the released Android app size?
A.Publish an app bundle so the store serves a per-device build
B.Remove every custom font from the application
C.Enable maximum compression for every resource in the project
D.Switch to a release build rather than profile
Answer: A
Ship an app bundle so Google Play generates per-device installs by architecture and screen density. Flutter also strips unused icons itself, but images and fonts in assets must be audited manually because they are always packaged in full.
What is required for a web link to open the app directly instead of a browser?
A.Declare a custom scheme for the application in the configuration file
B.The user must choose the app as the default handler
C.A file on the server verifying ownership of the domain
D.Register the domain with the corresponding app store
Answer: C
You need domain ownership verification: assetlinks.json for Android App Links and apple-app-site-association for iOS Universal Links, placed at the correct well-known path on an https server. Without this step, the link only opens the browser.
What is the standard way to support multiple languages in Flutter?
A.Use ARB files generating a string class through flutter_localizations
B.Set a global string map and look it up by language code
C.Load the strings from the server each time the app opens
D.Write the string-choosing condition at the point of display
Answer: A
Use flutter_localizations with ARB files per language, generating a typed string-access class. Beyond string lookup, this also handles plurals, gender, and locale-aware date, time, and currency formatting.
You need to pause video playback when the user switches apps. What should you use?
A.Check in the dispose of the video-playing widget
B.Set a timer periodically checking whether the app is visible
C.Listen for the video widget losing focus
D.Watch the lifecycle state through WidgetsBindingObserver
Answer: D
Mix WidgetsBindingObserver into State and handle didChangeAppLifecycleState. The states include resumed, inactive, paused, detached, and hidden; pause on paused or inactive depending on how sensitive the content is.
What is the correct way to report every uncaught error to a monitoring service?
A.Wrap runApp in a try-catch in main
B.Hook both FlutterError.onError and PlatformDispatcher's onError
C.Catch the exception in each API call with try-catch
D.Set ErrorWidget.builder to show a friendly error screen
Answer: B
You need two hooks: FlutterError.onError for errors raised inside the Flutter framework such as widget build errors, and PlatformDispatcher.instance.onError for asynchronous errors outside the framework. Attaching only one always loses half the errors.
Why do apps with complex deep linking usually move to go_router?
A.Because the paths are declared so the stack can be reconstructed
B.Because it animates screen transitions more smoothly than Navigator
C.Because it fully replaces Navigator in Flutter
D.Because it needs no BuildContext to navigate
Answer: A
Declarative navigation ties app state to a path, so opening a deep screen directly from a deep link or web URL can still rebuild the parent stack. With plain Navigator, this must be hand-written and is very error-prone.
A.It removes the need for Streams in the data layer
B.It lets the interface read the state without a context
C.It makes the state save itself to device storage automatically
D.Every change goes through one path, making it traceable
Answer: D
Separating events from state creates a single stream of changes: the UI sends events, the bloc processes them and emits new state. That lets you log the event sequence leading to a bug, test by pumping events and comparing state, and leaves no place to mutate state behind the scenes.
What advantage does ValueListenableBuilder have over setState at the screen root?
A.It allows updating the interface from another isolate
B.The value synchronizes automatically with other screens
C.No unsubscribing is needed when the widget leaves the tree
D.Only the part inside the builder is rebuilt on change
Answer: D
ValueListenableBuilder narrows the rebuild scope to just the part displaying that value. setState at the screen root rebuilds the whole child tree, including unrelated parts, and on complex screens that causes dropped frames.
When do you need a CustomScrollView with slivers instead of a plain ListView?
A.When several scrollable regions must share one axis
B.When you need pull-to-refresh
C.When the list has more than a thousand items
D.When the items have different heights
Answer: A
Use slivers when multiple different content regions must scroll as one block: a collapsing app bar, then a grid, then a list. Nesting scrollable widgets creates two competing scroll axes, while slivers have only one.
What does a Hero animation between two screens require?
A.Both screens must use the same AnimationController
B.The images on the two screens must share an aspect ratio
C.Two Hero widgets on the two routes sharing one tag
D.The source widget must be wrapped in a RepaintBoundary
Answer: C
The two Hero widgets in the two routes must share the same tag. During the route transition, Flutter lifts the widget onto an overlay and interpolates position and size from the old place to the new one. Duplicate tags within the same screen throw an error.
How do you detect the user scrolling near the end of a list to load more?
A.Trigger the load in the itemBuilder of the last item
B.Listen to a ScrollController and compare against maxScrollExtent
C.Set a timer checking the scroll position periodically
D.Count how many times the user swipes on the screen
Answer: B
Attach a ScrollController and compare position.pixels with position.maxScrollExtent minus a threshold, e.g. 200 pixels. You need a guard flag to avoid duplicate calls when scroll events fire continuously, and you must handle the no-more-data state.
Which states must a list screen handle to avoid a blank screen?
A.Loading failed, with a retry button
B.Loading for the first time
C.Loaded but with no data
D.The user has not granted notification permission
Answer: A, B, C
Three minimum states: loading, empty, and error with a retry button, alongside the has-data state. Omitting the empty state is the most common cause of an unexplained blank screen, and omitting the error branch leaves the user with no way out.
Why should autovalidateMode not be always on a signup form?
A.This mode slows down typing on weak devices
B.The user sees red errors before typing anything
C.This mode skips hand-written validators
D.This mode only works with TextFormField
Answer: B
always validates as soon as the form appears, so every empty field turns red before the user types anything. A sensible choice is onUserInteraction, or by default validate on submit and only then enable continuous validation.
How do you dismiss the keyboard when the user taps outside a text field?
A.Call the platform channel's hide-keyboard method
B.Call setState to rebuild the screen without the input field
C.Drop the current focus through the context's FocusScope
D.Set the input field to readOnly when tapping outside
Answer: C
Call FocusScope.of(context).unfocus(), usually inside a GestureDetector wrapping the whole screen. The keyboard is attached to the focused field, so losing focus closes the keyboard, and app state stays consistent.
How do you receive a result from a confirmation dialog?
A.Pass a callback into the dialog and call it on the button press
B.Set a global variable and read it after the dialog closes
C.await showDialog and read the popped value
D.Listen for the route closing through a RouteObserver
Answer: C
showDialog returns a Future that completes when the dialog closes, with the value passed to Navigator.pop. Dismissing by tapping outside returns null, so always handle that case instead of assuming a result.
Why show a snack bar through ScaffoldMessenger rather than Scaffold.of?
A.It needs no BuildContext to call
B.The snack bar survives when the screen is replaced
C.It allows showing several snack bars at once
D.It translates the content automatically into the system language
Answer: B
ScaffoldMessenger sits above individual Scaffolds, so a snack bar survives screen transitions. With Scaffold.of, the message is tied to the current Scaffold and disappears the moment that screen is replaced — exactly when the user most needs to read it.
Switching tabs and returning loses scroll position and loaded data. What is the fix?
A.Give each page in TabBarView a fixed key
B.Mix AutomaticKeepAliveClientMixin into the tab page
C.Increase how many pages TabBarView builds in advance
D.Save the scroll position to shared_preferences on every scroll
Answer: B
Mix AutomaticKeepAliveClientMixin into the page's State, set wantKeepAlive to true, and call super.build(context). TabBarView then keeps the page in memory, so scroll position and loaded data are preserved.
On tablets, which Material component replaces the bottom navigation bar?
A.Keep the bottom bar but make it taller
B.A TabBar placed just below the title bar
C.A NavigationRail placed vertically beside the content
D.A Drawer kept permanently open on the left
Answer: C
NavigationRail is the component for medium widths. Material 3 guidance has three tiers: below 600 use a bottom bar, from 600 to 840 use a vertical rail, and from 840 up use a navigation drawer always open beside the content.
What problem comes from hard-coding font sizes across an app?
A.The application will not run on a tablet
B.It ignores the system font size the user has set
C.The app store rejects the release
D.Text renders blurry on high-density screens
Answer: B
Users change the system font size for vision reasons, and an app with hard-coded font sizes ignores that setting. Flutter applies textScaler to Text, so the real problem is fixed-height layouts, which cause large text to be clipped or overflow.
Push notifications appear in the background but not while the app is open. Why?
A.A separate permission is needed for notifications while the app is showing
B.The device token is only valid while the app is in the background
C.With the app open, the application code receives it and handles it itself
D.The operating system blocks the notification to avoid interrupting
Answer: C
While the app is in the foreground, the OS hands the data to the app instead of drawing the notification itself. To show something, display a local notification or an in-app banner based on the data received in the relevant handler.
The user permanently denied camera permission. What should the app do?
A.Switch to a camera library that needs no permission
B.Request the permission again until the user agrees
C.Explain why and open the app's settings page directly
D.Block the application until the permission is granted
Answer: C
When permission is permanently denied, the permission request returns denied immediately without showing a dialog. The right approach is to briefly explain why the permission is needed, offer a button to open the app settings, and keep the rest of the app usable.
What is the main security concern when embedding a payment page in a WebView?
A.Restrict which domains it is allowed to navigate to
B.Only open the WebView while the device is on mobile data
C.Clear the cache after each time the page opens
D.Disable JavaScript to stop malicious code running in the page
Answer: A
You must control navigation: allow only trusted domains and block the rest or open them in the system browser. Users can't see the address bar in a WebView, so they can't tell on their own when the page has navigated somewhere else.
DevTools has a rebuild counter that marks directly on the widget tree the spots that build multiple times within a time window. It's the fastest way to find a setState placed too high or a missing const.
What does the obfuscate flag do in a release build and what is the trade-off?
A.It removes every string from the binary
B.It renames the symbols so stack traces become unreadable
C.It encrypts all the Dart code so it cannot be decompiled
D.It considerably reduces the application's startup time
Answer: B
--obfuscate renames classes and functions to short symbols, making reverse engineering harder. In exchange, stack traces become unreadable without the mapping file produced by --split-debug-info, so that file must be archived per release.
Where does the version field in pubspec.yaml map to at build time?
A.Before the plus is the version name and after it the build number
B.The whole string becomes the displayed version name
C.The build number is generated automatically from the build time
D.It is only used by pub.dev and does not affect the build
Answer: A
version: 1.4.2+37 splits into two parts: 1.4.2 is the display version name, and 37 is the build number. Stores reject uploads with a duplicate or lower build number, so this is the number that must be incremented on every release.
What is analysis_options.yaml used for in a Flutter project?
A.Enabling and disabling the compiler's experimental features
B.Configuring the static analysis rules and strictness level
C.Configuring code formatting such as line length and spacing
D.Declaring the dependencies used for analysing the code
Answer: B
It configures static analysis: enabling lint sets like flutter_lints, promoting warnings to errors, and turning on strict type modes. It turns many runtime errors into editor-time errors.
What is the difference between a package and a plugin in the Flutter ecosystem?
A.A package cannot depend on another package
B.A plugin must be approved by the Flutter team before release
C.A plugin has native code for each platform
D.A package only contains widgets while a plugin contains logic
Answer: C
A package is pure Dart code and runs on all platforms. A plugin includes native code for Android, iOS, web, or desktop, so it only works on platforms it supports and requires a rebuild when added.
A search field calls the API per keystroke and stale results overwrite fresh ones. What is the fix?
A.Only call the API when the user presses the search button
B.Increase the network request's timeout
C.Sort the results by time before displaying them
D.Debounce the input and cancel the previous request on further typing
Answer: D
You need two things: debounce for ~300ms to avoid calling on every keystroke, and cancel or ignore stale responses when a new query starts. Without the second part, a slow response from an old query can arrive later and overwrite the correct result.
Why do state classes need == and hashCode when used with state management libraries?
A.Because Dart requires every class to implement these two methods
B.Because the compiler needs them to optimize memory
C.Because the library compares the old and new state before redrawing
D.Because they are needed for converting to JSON
Answer: C
By default Dart compares by object identity, so two states with identical content are still considered different. State management libraries rely on this comparison to skip unnecessary rebuilds, so missing == and hashCode causes constant rebuilds.
Why should you not construct an ApiClient directly inside a widget?
A.Flutter forbids creating objects inside build
B.It cannot be swapped for a fake during testing
C.That object cannot be used inside an asynchronous function
D.The widget will not rebuild when the data changes
Answer: B
Dependencies buried inside a widget are not replaceable in tests, so widget tests are forced to make real network calls. Also, creating it inside build creates a new instance on every rebuild, losing cache and opening extra connections.
What is the main reason for a repository layer between UI and data sources?
A.It lets the interface read the data synchronously
B.It is mandatory in clean architecture so it must be there
C.It reduces the number of network calls without needing a cache
D.The interface does not depend on which data source is used
Answer: D
A repository separates what to fetch from where to fetch it from. The UI just calls one method without knowing if data comes from network, cache, or local database, so changing sources or adding offline mode doesn't affect the widget layer.