aedev.net
  • Trang chủ
  • AI
  • Mobile
  • Flutter
  • React Native
  • Backend
  • DevOps
  • Hướng dẫn
No Result
View All Result
SAVED POSTS
aedev.net
  • Trang chủ
  • AI
  • Mobile
  • Flutter
  • React Native
  • Backend
  • DevOps
  • Hướng dẫn
No Result
View All Result
aedev.net
No Result
View All Result
Minh họa phát triển ứng dụng mobile đa nền tảng với Flutter

Flutter DropdownButton: value cần khớp đúng một item, không phải một nhãn

Suong Nguyen by Suong Nguyen
09/11/2026
in Flutter
0
585
SHARES
3.2k
VIEWS
Summarize with ChatGPTShare to Facebook

Danh sách có hai nhóm cùng tên “Mobile”, và DropdownButton báo rằng giá trị đang chọn không khớp đúng một item. Thường lỗi bắt đầu khi ứng dụng dùng nhãn hiển thị làm định danh. Hai dòng giống chữ không nhất thiết là cùng một thực thể; dropdown cần một giá trị phân biệt chúng rõ ràng.

Bài đối chiếu Flutter API ngày 09/11/2026. Ví dụ Material dưới đây được rà theo tài liệu và chữ ký widget, chưa chạy Flutter SDK, build, widget test hoặc thiết bị. Khi áp dụng, kiểm tra lại trên phiên bản SDK và nền tảng của dự án.

Bài tập trung vào màn hình đang dùng DropdownButton. Trang lớp DropdownButton còn hướng dẫn chuyển sang DropdownMenu cho ứng dụng Material 3; hai API có cách quản lý lựa chọn khác nhau, nên không áp dụng nguyên prop của ví dụ này cho widget mới.

Tách ID khỏi chữ người dùng nhìn thấy

DropdownButton constructor yêu cầu các item có giá trị phân biệt. Khi value không null, lựa chọn cần khớp một item. DropdownMenuItem.value là giá trị được trả về qua onChanged, còn child có thể hiển thị nhãn khác.

Ví dụ dùng chuỗi ID cho cả item và state được chọn, giúp việc so khớp đơn giản. Không đưa object vừa tạo lại ở mỗi lần tải vào value rồi trông chờ mặc định mọi class đều so bằng nội dung. Nếu ứng dụng dùng object, cần hiểu rõ quy tắc equality của kiểu đó.

Một màn hình có hai nhãn giống nhau

Đặt vào lib/main.dart của dự án Material thử nghiệm:

import 'package:flutter/material.dart';

void main() => runApp(const MaterialApp(home: TeamPicker()));

class TeamOption {
  const TeamOption(this.id, this.label);
  final String id;
  final String label;
}

class TeamPicker extends StatefulWidget {
  const TeamPicker({super.key});
  @override
  State<TeamPicker> createState() => _TeamPickerState();
}

class _TeamPickerState extends State<TeamPicker> {
  static const teams = [
    TeamOption('mobile-hn', 'Mobile'),
    TeamOption('mobile-hcm', 'Mobile'),
    TeamOption('backend', 'Backend'),
  ];
  String? selectedId;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Chọn nhóm')),
      body: Padding(
        padding: const EdgeInsets.all(24),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            DropdownButton<String>(
              value: selectedId,
              hint: const Text('Chưa chọn nhóm'),
              items: teams.map((team) {
                return DropdownMenuItem<String>(
                  value: team.id,
                  child: Text('${team.label} (${team.id})'),
                );
              }).toList(),
              onChanged: (nextId) {
                setState(() => selectedId = nextId);
              },
            ),
            Text('ID đã chọn: ${selectedId ?? "chưa có"}'),
          ],
        ),
      ),
    );
  }
}

Hai dòng Mobile có ID khác nhau; ví dụ hiển thị thêm ID trong menu để người thử phân biệt được. Trong sản phẩm, nên dùng thông tin có ý nghĩa với người dùng như địa điểm hoặc tên đơn vị thay vì bắt họ nhớ mã nội bộ. Điều kiện cần giữ là value ổn định và duy nhất.

Kiểm tra giá trị null và từng lựa chọn

Khi chưa chọn, selectedId bằng null và hint dự định xuất hiện. Chọn lần lượt Mobile ở Hà Nội, Mobile ở TP.HCM và Backend, rồi kiểm tra dòng ID phía dưới. Hai lựa chọn Mobile phải có thể dẫn đến hai ID khác nhau dù cùng label gốc.

Theo DropdownButton.value, null là trạng thái chưa chọn có cách hiển thị riêng. Đừng dùng chuỗi rỗng làm đại diện ngầm cho null nếu danh sách không có item mang giá trị rỗng; điều đó tạo một giá trị khác nhưng vẫn không khớp item nào.

Khi danh sách thay đổi sau một lần tải

Ví dụ giữ danh sách cố định để làm rõ định danh. Với dữ liệu động, một selectedId hợp lệ ở lượt trước có thể biến mất sau khi lọc hoặc tải lại. Trước khi render tập options mới, kiểm tra xem ID cũ còn có đúng một đối tác trong tập ấy không. Nếu không còn, chọn chính sách rõ ràng: xóa lựa chọn về null hoặc yêu cầu người dùng chọn lại.

Nếu backend gửi hai bản ghi trùng ID, không sửa bằng cách chỉ đổi label. Rà nguồn dữ liệu và quyết định bản ghi nào hợp lệ. Tự gắn index vào value có thể làm lựa chọn đổi nghĩa khi sắp xếp lại danh sách, nên nó không thay thế một ID ổn định.

Đọc assertion để khoanh vùng lỗi

Constructor công khai có kiểm tra số item khớp value. Với danh sách không rỗng và value khác null, hãy đếm số item có value bằng lựa chọn hiện tại: 0 gợi ý lựa chọn đã mất hoặc sai kiểu/giá trị; từ 2 trở lên gợi ý định danh bị trùng. Đây là thao tác chẩn đoán dữ liệu, không phải lý do để tắt assertion.

Kế hoạch kiểm tra tiếp theo nên có danh sách rỗng, ID bị xóa, ID trùng và hai label giống nhau nhưng ID khác. Phần sửa cốt lõi là để state lưu định danh của lựa chọn, còn label chỉ phục vụ hiển thị. Nhờ vậy, việc đổi nhãn hoặc dịch giao diện không tự làm đổi thực thể được chọn.

Nguồn tham khảo

  • Flutter: DropdownButton và hướng dẫn Material 3
  • Flutter: DropdownButton constructor
  • Flutter: DropdownButton.value
  • Flutter: DropdownMenuItem.value

Tags: DropdownButtonFlutterForm UI
SummarizeShare234
Suong Nguyen

Suong Nguyen

Related Stories

Minh họa phát triển ứng dụng mobile đa nền tảng với Flutter

Flutter AnimatedOpacity: opacity bằng 0 chưa tự chặn thao tác chạm

by Suong Nguyen
10/11/2026
0

Tách độ trong suốt, hit testing và semantics khi làm nút biến mất bằng AnimatedOpacity, với cùng một state điều khiển từng phần.

Minh họa phát triển ứng dụng mobile đa nền tảng với Flutter

Flutter TextField: readOnly khác enabled như thế nào với nút suffix?

by Suong Nguyen
08/11/2026
0

Chọn trạng thái TextField khi cần ngăn sửa nội dung, vẫn cho chọn chữ hoặc giữ nút suffix hoạt động, kèm màn hình kiểm tra hai trường.

Minh họa phát triển ứng dụng mobile đa nền tảng với Flutter

Flutter InkWell: đặt nền và clip ở Material để thấy ripple đúng góc

by Suong Nguyen
07/11/2026
0

Dựng một thẻ tương tác với Material, Ink và InkWell, rồi kiểm tra vị trí vẽ ripple cùng vùng cắt bo góc.

Minh họa phát triển ứng dụng mobile đa nền tảng với Flutter

Flutter CheckboxListTile: value và selected không tự đồng bộ

by Suong Nguyen
06/11/2026
0

Cập nhật giá trị checkbox trong state, phân biệt selected của cả tile và khóa tương tác bằng onChanged null.

Next Post
Minh họa pipeline CI/CD từ commit đến deploy cho team nhỏ

Git revert: tạo commit đảo thay đổi cũ và giữ phần việc đến sau

0 0 votes
Article Rating
Subscribe
Login
Notify of
guest
guest
0 Comments
Oldest
Newest Most Voted
AE Dev

AE Dev mang đến các bài viết về lập trình, mobile app, backend, frontend, WordPress và công nghệ, phù hợp cho developer muốn học hỏi và cập nhật kiến thức thực tế.

Recent Posts

  • React Native Text selectable: cho người dùng chọn và sao chép mã hiển thị
  • Phỏng vấn JavaScript: object mặc định của tham số được tạo khi nào?
  • Android runOnUiThread và Handler.post: chạy ngay hay đưa vào hàng đợi?

Categories

  • AI
  • Backend
  • Đánh giá
  • DevOps
  • Flutter
  • Hướng dẫn
  • Lập trình Mobile
  • Phỏng vấn
  • React Native
  • Uncategorized

Weekly Newsletter

  • Buy JNews
  • Support Forum
  • Pre-sale Question
  • Contact Us

© 2026 AE Dev - Blog công nghệ, lập trình và chia sẻ kiến thức IT.

Welcome Back!

Login to your account below

Forgotten Password?

Retrieve your password

Please enter your username or email address to reset your password.

Log In
No Result
View All Result
  • Trang chủ
  • AI
  • Mobile
  • React Native
  • Backend
  • DevOps
  • Hướng dẫn
  • Flutter

© 2026 AE Dev - Blog công nghệ, lập trình và chia sẻ kiến thức IT.

wpDiscuz
0
0
Would love your thoughts, please comment.x
()
x
| Reply