PRM393Chưa đoKỳ 8Chuyên ngành Cập nhật 07/09/2026

Lập trình di động (Flutter) - Mobile Programming

Lập trình di động với Flutter là môn học xây dựng ứng dụng đa nền tảng Android và iOS bằng Flutter và ngôn ngữ Dart. Ngân hàng câu hỏi trắc nghiệm PRM393 có giải thích bao quát trọn bộ chương trình: cài đặt Flutter SDK, cấu trúc project, hot reload và DevTools, nền tảng Dart (kiểu dữ liệu, null safety, class, collection, Map, generics, mixin, package và import), lập trình bất đồng bộ với Future, async/await, Stream, StreamController và StreamBuilder, dựng giao diện bằng widget tree, Scaffold, ListView, ThemeData, bố cục Row/Column, GridView, Stack, LayoutBuilder, MediaQuery và responsive UI, điều hướng với Navigator 1.0/2.0, named route, deep link và guarded route, form với TextEditingController và validation, gọi REST API bằng http, parse JSON, FutureBuilder, phân trang và caching, lưu trữ cục bộ bằng SharedPreferences, SQLite (sqflite) và Hive, xác thực bằng token và refresh token, quản lý state với setState, Provider, BLoC và Cubit, animation với Tween cùng AnimatedSwitcher, tối ưu hiệu năng bằng RepaintBoundary và thu hẹp phạm vi rebuild, kiểm thử unit/widget/integration, quản lý mã nguồn bằng Git và build - release ứng dụng. Tài liệu ôn thi FE dành cho sinh viên FPT University.

512Câu hỏi
1Bộ đề
15Chủ đề
5,02 đánh giá

Câu hỏi của môn

304/512 câuCòn 208
AIt allows a widget to rebuild only when a specific part of a model changes, rather than the entire model.
BIt allows a single child widget to be scrollable when it exceeds the screen's vertical or horizontal space.
CIt manages the focus state of a specific widget, such as a text field, and handles keyboard events.
DIt allows a constructor to return an existing instance or a subclass instance instead of always creating a new one.
Lời giải
Widget Selector từ gói Provider giúp cải thiện hiệu suất bằng cách cho phép một widget được xây dựng lại chỉ khi một phần cụ thể của mô hình thay đổi, thay vì toàn bộ mô hình. Điều này giúp giảm thiểu việc xây dựng lại không cần thiết và cải thiện hiệu suất của ứng dụng. Khi một phần của mô hình thay đổi, Selector sẽ chỉ cập nhật phần đó, thay vì cập nhật toàn bộ mô hình. Điều này giúp giảm thiểu việc sử dụng tài nguyên và cải thiện hiệu suất của ứng dụng. Ngoài ra, Selector cũng giúp giảm thiểu việc xây dựng lại không cần thiết khi một widget không bị ảnh hưởng bởi thay đổi của mô hình.
Mở trang câu hỏi này →
ATrue
BFalse
Lời giải
Trong Flutter, CircularProgressIndicator là widget tiêu chuẩn để chỉ định trạng thái đang tải. Nó thường được sử dụng để hiển thị trạng thái chờ hoặc tải dữ liệu. CircularProgressIndicator có thể được tùy chỉnh để phù hợp với thiết kế và màu sắc của ứng dụng. Nó thường được sử dụng trong các trường hợp như tải dữ liệu từ mạng, tải hình ảnh hoặc video, hoặc trong quá trình xử lý dữ liệu. CircularProgressIndicator giúp người dùng hiểu được ứng dụng đang làm gì và chờ đợi kết quả.
Mở trang câu hỏi này →
ATrue
BFalse
Lời giải
Widget 'Selector' hiệu suất cao hơn so với 'Provider.of' vì nó chỉ cập nhật lại khi dữ liệu cụ thể thay đổi. Điều này giúp giảm thiểu việc rebuild widget không cần thiết, từ đó tăng hiệu suất của ứng dụng. Trong khi đó, 'Provider.of' thường sẽ rebuild widget khi có bất kỳ thay đổi nào trong dữ liệu, dẫn đến lãng phí tài nguyên và giảm hiệu suất.
Mở trang câu hỏi này →
AOnly for animation
BPush data down the tree without passing every constructor arg
COnly draw borders
DReplace `Navigator`
Lời giải
InheritedWidget và các lớp bọc như Provider giúp chúng ta truyền dữ liệu xuống cây widget mà không cần phải truyền từng tham số vào mỗi constructor. Điều này giúp giảm bớt sự phức tạp khi xây dựng ứng dụng, đặc biệt là khi chúng ta cần truyền dữ liệu từ trên cao xuống dưới. Ví dụ, nếu chúng ta muốn truyền một giá trị từ màn hình chính xuống các màn hình con, chúng ta có thể sử dụng InheritedWidget để truyền giá trị đó xuống cây widget. Điều này giúp chúng ta tránh được việc phải truyền từng tham số vào mỗi constructor, làm cho mã code trở nên dễ đọc và dễ bảo trì hơn. Ngoài ra, InheritedWidget cũng giúp chúng ta chia sẻ dữ liệu giữa các widget khác nhau, giúp chúng ta xây dựng ứng dụng phức tạp hơn mà không cần phải lo lắng về việc truyền dữ liệu.
Mở trang câu hỏi này →
289What does context.read() do in Provider?4 lựa chọnTrung bình67% trả lời đúng
ACreates provider
BListens to changes
CDisposes provider
DReads value without listening
Lời giải
Trong quá trình sử dụng Provider, context.read() đóng vai trò quan trọng. Nó cho phép bạn đọc giá trị của provider mà không cần lắng nghe các thay đổi sau này. Điều này đặc biệt hữu ích khi bạn cần truy cập vào giá trị của provider một lần và không cần cập nhật khi giá trị thay đổi. Context.read() khác với context.watch() ở chỗ, nó không lắng nghe các thay đổi sau này, vì vậy nó không gây ra bất kỳ hiệu ứng phụ nào. Điều này giúp bạn có thể sử dụng Provider một cách linh hoạt và hiệu quả hơn.
Mở trang câu hỏi này →
ADoes not exist
BRebuild only when the selected slice of state changes — fewer rebuilds
CPick colors
DReplace `Navigator`
Lời giải
Provider Selector là một tính năng giúp giảm thiểu số lần rebuild trong ứng dụng Flutter. Khi sử dụng Provider, ứng dụng của bạn sẽ rebuild mỗi khi trạng thái thay đổi. Tuy nhiên, nếu bạn chỉ muốn rebuild một phần của trạng thái, thì Provider Selector sẽ giúp bạn thực hiện điều đó. Nó giúp bạn chọn một phần cụ thể của trạng thái và chỉ rebuild khi phần đó thay đổi. Điều này giúp giảm thiểu số lần rebuild và cải thiện hiệu suất của ứng dụng.
Mở trang câu hỏi này →
291What does setState() do?4 lựa chọnDễ100% trả lời đúng
ADeletes widget
BUpdates UI
CStops app
DChanges theme only
Lời giải
setState() là một phương thức quan trọng trong React, giúp cập nhật trạng thái của một widget. Khi bạn gọi setState(), React sẽ tự động cập nhật giao diện người dùng (UI) để phản ánh những thay đổi mới. Điều này xảy ra vì setState() sẽ tạo ra một sự kiện mới, khiến React phải tái tạo lại giao diện người dùng. Điều này giúp đảm bảo rằng giao diện người dùng luôn được cập nhật một cách chính xác và đồng bộ với trạng thái của ứng dụng. Ngoài ra, setState() cũng giúp ứng dụng của bạn trở nên linh hoạt và dễ dàng thay đổi, giúp bạn có thể tạo ra những ứng dụng phức tạp và đa dạng mà không gặp phải bất kỳ vấn đề nào.
Mở trang câu hỏi này →
AFaster rendering
BImproved navigation
CBetter animations
DSimpler state sharing and management
Lời giải
Provider là một công cụ quan trọng trong Flutter giúp quản lý và chia sẻ trạng thái giữa các widget. Khi sử dụng Provider, bạn có thể dễ dàng quản lý trạng thái của ứng dụng và cập nhật trạng thái cho các widget con. Điều này giúp đơn giản hóa quá trình chia sẻ và quản lý trạng thái, giảm thiểu sự phức tạp trong việc quản lý trạng thái của ứng dụng.
Mở trang câu hỏi này →
AMemory management
BState persistence
CEfficient data propagation
DAutomatic layout
Lời giải
InheritedWidget là một loại widget trong Flutter có thể truyền dữ liệu từ cha sang con mà không cần phải tạo một chuỗi widget mới. Lợi ích chính của InheritedWidget là giúp truyền dữ liệu một cách hiệu quả và tiết kiệm thời gian. Khi sử dụng InheritedWidget, bạn có thể dễ dàng truy cập và sử dụng dữ liệu từ cha widget mà không cần phải truyền qua từng widget con. Điều này giúp giảm thiểu số lượng widget và cải thiện hiệu suất của ứng dụng. Ngoài ra, InheritedWidget cũng giúp duy trì trạng thái của ứng dụng một cách ổn định và hiệu quả.
Mở trang câu hỏi này →
ACreate state
BListen and rebuild specific parts of the UI
CDefine themes
DManage navigation
Lời giải
Trong Provider, Consumer widget đóng vai trò quan trọng trong việc giao tiếp giữa Provider và Consumer. Nó cho phép Consumer lắng nghe và cập nhật trạng thái từ Provider. Khi trạng thái thay đổi, Consumer sẽ được thông báo và rebuild lại các phần của giao diện người dùng (UI) cần thiết. Điều này giúp đảm bảo giao diện người dùng luôn được cập nhật và phản ánh đúng trạng thái dữ liệu. Consumer widget không tạo ra trạng thái mới, cũng không định nghĩa chủ đề hoặc quản lý điều hướng. Nó chỉ đơn giản là lắng nghe và phản ứng với các thay đổi trạng thái từ Provider.
Mở trang câu hỏi này →
295What problem does state lifting help solve?4 lựa chọnTrung bình67% trả lời đúng
ASharing state between widgets
BAPI errors
CLayout overflow
DUI rendering
Lời giải
State lifting là một kỹ thuật giúp giải quyết vấn đề chia sẻ trạng thái giữa các widget. Khi một widget cần truy cập vào trạng thái của widget khác, việc chia sẻ trạng thái trực tiếp có thể dẫn đến sự phức tạp và khó khăn trong việc quản lý trạng thái. State lifting giúp giải quyết vấn đề này bằng cách di chuyển trạng thái lên một cấp độ cao hơn, thường là cấp độ của widget cha hoặc cấp độ ứng dụng. Điều này cho phép các widget con truy cập vào trạng thái mà không cần phải chia sẻ trạng thái trực tiếp. Kỹ thuật này giúp giảm thiểu sự phức tạp và khó khăn trong việc quản lý trạng thái, đồng thời cải thiện hiệu suất và tính linh hoạt của ứng dụng.
Mở trang câu hỏi này →
296When should you prefer Provider over setState()?4 lựa chọnTrung bình67% trả lời đúng
AFor global or shared state
BFor navigation
CFor simple UI updates
DFor animations
Lời giải
Khi nào bạn nên ưu tiên Provider so với setState()? Provider là một công cụ mạnh mẽ trong React Native giúp bạn quản lý state toàn cầu hoặc chung. Nó cho phép bạn chia sẻ state giữa các component khác nhau trong ứng dụng của mình. Điều này đặc biệt hữu ích khi bạn cần cập nhật state trong nhiều component khác nhau. Ví dụ, khi bạn muốn hiển thị thông tin người dùng trên nhiều màn hình khác nhau, bạn có thể sử dụng Provider để chia sẻ state người dùng. Điều này giúp giảm thiểu việc sử dụng setState() và làm cho code của bạn trở nên dễ đọc và dễ bảo trì hơn.
Mở trang câu hỏi này →
297When use `MultiProvider`?4 lựa chọn
AOnly one model
BDoes not exist
CReplace `MaterialApp`
DProvide several `Provider`/`ChangeNotifierProvider` roots for a subtree
Lời giải
Khi sử dụng `MultiProvider`, mục đích chính là để cung cấp nhiều nguồn dữ liệu cho một phần tử con trong cây widget. Điều này đặc biệt hữu ích khi bạn cần truy cập và sử dụng nhiều nguồn dữ liệu khác nhau trong một phần tử con, mà không cần phải di chuyển lên cây widget cha. `MultiProvider` cho phép bạn tạo ra nhiều nguồn dữ liệu khác nhau và cung cấp chúng cho phần tử con mà không cần phải tạo ra một cây widget mới. Điều này giúp giảm thiểu số lượng widget và cải thiện hiệu suất của ứng dụng.
Mở trang câu hỏi này →
Aselect()
Blisten()
Cwatch()
Dread()
Lời giải
Để trả lời câu hỏi này, chúng ta cần hiểu về Provider trong Flutter. Provider là một thư viện giúp quản lý trạng thái ứng dụng. Nó cung cấp một số phương thức để lắng nghe thay đổi trạng thái và cập nhật giao diện người dùng. Trong các phương thức này, phương thức nào lắng nghe thay đổi trạng thái và rebuild giao diện người dùng?
Mở trang câu hỏi này →
ATrue
BFalse
Lời giải
LayoutBuilder là một công cụ trong Flutter giúp xác định bố cục dựa trên các hạn chế của widget cha chứ không phải dựa trên kích thước toàn bộ màn hình. Điều này cho phép bạn tạo ra các bố cục linh hoạt và phù hợp với từng trường hợp sử dụng khác nhau. Ví dụ, bạn có thể sử dụng LayoutBuilder để tạo ra một bố cục khác nhau cho các thiết bị di động và máy tính để bàn. Ngoài ra, LayoutBuilder cũng giúp bạn tối ưu hóa hiệu suất của ứng dụng bằng cách giảm thiểu số lượng các widget cần được tái tạo khi kích thước màn hình thay đổi.
Mở trang câu hỏi này →
ATrue
BFalse
Lời giải
MediaQuery là một tính năng trong CSS giúp bạn có thể lấy thông tin về kích thước màn hình và hướng của thiết bị. Nó cho phép bạn viết mã CSS khác nhau dựa trên kích thước màn hình và hướng của thiết bị. Ví dụ, bạn có thể viết mã CSS để thay đổi kích thước font chữ dựa trên kích thước màn hình. Điều này giúp bạn có thể tối ưu hóa trải nghiệm người dùng trên các thiết bị khác nhau.
Mở trang câu hỏi này →
ATrue
BFalse
Lời giải
Widget 'SafeArea' được sử dụng để đảm bảo giao diện người dùng không bị che bởi các tính năng phần cứng như notch camera. Nó giúp ngăn chặn các phần của giao diện người dùng bị che bởi notch camera hoặc các tính năng phần cứng khác. Điều này giúp đảm bảo giao diện người dùng luôn được hiển thị đầy đủ và không bị ảnh hưởng bởi các tính năng phần cứng.
Mở trang câu hỏi này →
AOnly responsive exists
BAdaptive is only font size
CAdaptive changes navigation/platform patterns (rail vs bottom bar); responsive changes layout by space
DSame
Lời giải
Adaptive và responsive là hai thuật ngữ thường được sử dụng trong thiết kế giao diện người dùng (UI) và thiết kế trải nghiệm người dùng (UX). Adaptive và responsive đều liên quan đến việc thiết kế giao diện để phù hợp với các thiết bị di động khác nhau, nhưng chúng có cách tiếp cận khác nhau. Adaptive tập trung vào việc thay đổi các mẫu giao diện dựa trên các yếu tố như loại thiết bị, hệ điều hành và kích thước màn hình. Ví dụ, một ứng dụng có thể sử dụng giao diện rail trên điện thoại di động và giao diện bar dưới trên máy tính bảng. Ngược lại, responsive tập trung vào việc thay đổi bố cục giao diện dựa trên không gian màn hình. Điều này có nghĩa là giao diện sẽ tự động điều chỉnh kích thước và bố cục để phù hợp với kích thước màn hình của thiết bị.
Mở trang câu hỏi này →
ADesktop only
BSame
C`viewInsets` (often bottom) grows when IME covers; `padding` is safe area/notch
DNot usable in Flutter
Lời giải
Khi bàn phím mở, `MediaQuery.paddingOf(context)` và `viewInsetsOf` có cách xử lý khác nhau. `viewInsetsOf` thường sẽ tăng lên khi bàn phím hoặc bàn di chuột mở ra, đặc biệt là phần dưới. Điều này có thể gây ra vấn đề với thiết kế của bạn. Ngược lại, `MediaQuery.paddingOf(context)` sẽ cung cấp khoảng cách an toàn (safe area) hoặc khoảng cách cho notch trên thiết bị. Điều này giúp bạn tránh được các vấn đề về thiết kế khi bàn phím hoặc bàn di chuột mở ra. Vì vậy, khi bàn phím mở, `viewInsets` thường sẽ tăng lên, trong khi `padding` là khoảng cách an toàn.
Mở trang câu hỏi này →
304How does `LayoutBuilder` differ from `MediaQuery` in creating responsive UIs?4 lựa chọnDễ100% trả lời đúng
AIt helps Flutter's framework uniquely identify widgets to preserve state during list modifications.
BMediaQuery provides device screen dimensions, while LayoutBuilder provides the constraints of the parent widget.
CA feature that automatically triggers validation logic without waiting for a manual submit button press.
DIt creates a Future that completes after a specified duration, often used to simulate network latency.
Lời giải
LayoutBuilder và MediaQuery là hai cách khác nhau để tạo giao diện người dùng phản hồi trong Flutter. Cả hai đều được sử dụng để tạo ra các ứng dụng có thể tương tác với nhiều kích thước màn hình khác nhau. Tuy nhiên, LayoutBuilder khác với MediaQuery ở chỗ nó cung cấp các hạn chế của widget cha, trong khi MediaQuery cung cấp kích thước màn hình của thiết bị. Điều này có nghĩa là LayoutBuilder cho phép bạn tạo ra các ứng dụng có thể tự điều chỉnh kích thước dựa trên các hạn chế của widget cha, trong khi MediaQuery cho phép bạn tạo ra các ứng dụng có thể tự điều chỉnh kích thước dựa trên kích thước màn hình của thiết bị. Ví dụ, bạn có thể sử dụng LayoutBuilder để tạo ra một ứng dụng có thể tự điều chỉnh kích thước của nó dựa trên kích thước của màn hình, trong khi bạn có thể sử dụng MediaQuery để tạo ra một ứng dụng có thể tự điều chỉnh kích thước của nó dựa trên kích thước của màn hình và các yếu tố khác.
Mở trang câu hỏi này →