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 Wrap: cho nhóm Chip xuống dòng và tách spacing với runSpacing

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

Một hàng nhãn công nghệ thường nhìn ổn khi chỉ có hai Chip ngắn. Thêm nhãn tiếng Việt dài hoặc thu hẹp cửa sổ, Row không tự chuyển các Chip còn lại xuống hàng. Wrap phù hợp khi yêu cầu là một nhóm phần tử lần lượt lấp đầy từng dòng rồi tiếp tục ở dòng mới.

Bài đối chiếu API Flutter Wrap và Row hiện hành ngày 05/11/2026. Ví dụ Dart được rà thủ công theo hợp đồng widget; chưa chạy Flutter SDK, build app hay đo layout trên thiết bị. Các bước quan sát bên dưới là checklist để bạn tự chạy trong project, không phải ảnh chụp hoặc số đo đã thu được.

Chọn đúng kiểu bố trí cho nhóm nhãn

Row bố trí con trong một hàng ngang. Wrap có thể tạo nhiều run, tức nhiều lượt bố trí theo trục chính; với hướng ngang mặc định, mỗi run thường được nhìn như một dòng. Khi phần tử tiếp theo không còn vừa, Wrap bắt đầu run mới.

Đừng nhầm nhóm Chip xuống dòng với nội dung Text xuống dòng bên trong một Chip. Wrap quyết định vị trí của các widget con. Một nhãn riêng quá dài vẫn cần quy tắc riêng cho nội dung và chiều rộng của chính widget đó.

1. Demo có giới hạn chiều rộng rõ ràng

Dùng đoạn sau làm nội dung lib/main.dart trong project Flutter đã tạo. Ví dụ không cần package bên ngoài:

import 'package:flutter/material.dart';

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

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

  static const tags = <String>[
    'Dart',
    'Flutter',
    'Kiểm thử giao diện',
    'Mobile',
    'Backend',
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Nhóm nhãn tự xuống dòng')),
      body: SingleChildScrollView(
        padding: const EdgeInsets.all(16),
        child: Align(
          alignment: Alignment.topLeft,
          child: ConstrainedBox(
            constraints: const BoxConstraints(maxWidth: 320),
            child: Wrap(
              spacing: 8,
              runSpacing: 12,
              children: tags.map((tag) => Chip(
                label: Text(tag),
              )).toList(),
            ),
          ),
        ),
      ),
    );
  }
}

ConstrainedBox giới hạn nhóm nhãn tối đa 320 logical pixel, đồng thời vẫn chịu ràng buộc từ vùng cha. Đây không phải cam kết rằng đúng ba Chip sẽ nằm trên dòng đầu: số lượng phụ thuộc font, theme, text scale và kích thước thực của từng Chip.

SingleChildScrollView cho phép cuộn dọc nếu vùng nội dung thấp. Nó không biến Wrap thành danh sách lazy. Toàn bộ children trong ví dụ vẫn được tạo từ danh sách tags.

2. Tách khoảng cách trong dòng khỏi khoảng cách giữa dòng

spacing: 8 tạo khoảng cách giữa các phần tử kề nhau theo trục chính. Với Wrap ngang, đó là khoảng cách giữa các hộp Chip trong cùng run. runSpacing: 12 đặt khoảng cách giữa các run theo trục còn lại.

Hai số này không thay thế padding của trang hoặc padding bên trong Chip. Nếu tổng khoảng trắng nhìn lớn hơn dự kiến, kiểm tra thêm các khoảng đệm và vùng chạm do component con hoặc theme tạo ra. Đo bounds của widget trước khi kết luận Wrap cộng sai spacing.

Trong ví dụ, alignment mặc định bắt đầu mỗi run từ phía start theo hướng văn bản. Nếu cần đổi căn hàng, xem alignment; nếu cần căn cả tập hợp các run trong vùng trống, xem runAlignment. Chúng giải quyết hai cấp bố trí khác nhau.

Kiểm tra với bề rộng và nội dung thay đổi

Đầu tiên chạy với nhóm năm nhãn, sau đó thu hẹp vùng hiển thị. Kiểm tra các Chip chuyển sang run tiếp theo khi không còn chỗ, vẫn giữ thứ tự dữ liệu và không bị một container có chiều cao cố định cắt mất dòng cuối.

Tiếp theo tăng cỡ chữ trong cài đặt thiết bị hoặc môi trường test của app. Thêm một nhãn rất dài và kiểm tra riêng cách component con xử lý nó. Nếu thiết kế cần rút gọn nhãn, đặt chính sách maxLines và overflow phù hợp với khả năng đọc; không coi xuống dòng giữa các Chip là giải pháp cho mọi nhãn dài.

Đổi danh sách thành rỗng rồi một phần tử để kiểm tra trạng thái ít dữ liệu. Đổi direction sang dọc chỉ khi yêu cầu thiết kế thật sự là lấp theo cột: ý nghĩa của trục spacing và runSpacing cũng đổi theo hướng ấy.

Lỗi thường gặp và phạm vi sử dụng

Đặt Wrap ngang trong một vùng có chiều rộng không bị giới hạn có thể khiến nó không xuống dòng theo mong đợi. Xác định bề rộng khả dụng từ layout cha trước khi chỉnh spacing. Không bọc từng Chip bằng Expanded như trong Row: Expanded yêu cầu cha Flex phù hợp, trong khi Wrap là kiểu bố trí khác.

Dùng Wrap cho nhóm nhãn có số lượng vừa phải và phần tử có chiều rộng khác nhau. Với dữ liệu dài cần dựng theo nhu cầu, xem các widget danh sách hoặc grid phù hợp. Bắt đầu bằng yêu cầu hiển thị và ràng buộc thực tế; việc thay Row bằng Wrap chỉ đúng khi sản phẩm chấp nhận nhiều dòng.

Nguồn tham khảo

  • Flutter: Wrap và các thuộc tính bố trí
  • Flutter: Row và nguyên nhân overflow

Tags: FlutterLayoutWrap
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 ListView.separated: itemCount đếm dữ liệu, không đếm separator

by Suong Nguyen
04/11/2026
0

Tách itemBuilder và separatorBuilder để thêm khoảng cách giữa các dòng mà không lệch index hoặc tạo đường phân cách thừa ở cuối danh sách.

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

Flutter AnimatedSwitcher: đổi nội dung cần đúng key để có transition

by Suong Nguyen
03/11/2026
0

Dùng bộ đếm nhỏ để phân biệt cập nhật một Text hiện có với thay child của AnimatedSwitcher bằng ValueKey theo dữ liệu.

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

Flutter RefreshIndicator: kéo làm mới cả danh sách ngắn

by Suong Nguyen
02/11/2026
0

Đặt AlwaysScrollableScrollPhysics trên ListView và trả đúng Future của lượt tải để thao tác kéo làm mới có vòng đời rõ ràng.

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

Flutter SafeArea: minimum và MediaQuery padding không phải cộng tay

by Suong Nguyen
01/11/2026
0

Đặt SafeArea đúng cấp, hiểu minimum và lý do MediaQuery.padding thay đổi trong subtree đã được xử lý inset.

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 pointerEvents: lớp phủ box-none vẫn cho nút con nhận chạm
  • Destructuring default: vì sao undefined nhận mặc định còn null thì không?
  • Android Uri.Builder: thêm query parameter mà không ghép chuỗi thủ công

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