Flutter: Hướng dẫn xây dựng bổ cục trong Flutter


Các khóa học qua video:
Python SQL Server PHP C# Lập trình C Java HTML5-CSS3-JavaScript
Học trên YouTube <76K/tháng. Đăng ký Hội viên
Đăng ký nhận thông báo về những video mới nhất

Những gì bạn sẽ học:

  • Cơ chế bố cục của Flutter hoạt động như thế nào.
  • Cách sắp xếp các widget theo chiều dọc và chiều ngang.
  • Cách xây dựng bố cục trong Flutter.

Đây là hướng dẫn xây dựng bố cục trong Flutter. Bạn sẽ xây dựng bố cục cho ứng dụng sau:

Ứng dụng đã hoàn thành
Ứng dụng đã hoàn thành

Bài hướng dẫn này sẽ giải thích cách tiếp cận bố cục của Flutter và chỉ ra cách đặt một tiện ích con trên màn hình. Sau khi thảo luận về cách sắp xếp các widget theo chiều ngang và chiều dọc, một số widget bố cục phổ biến nhất sẽ được đề cập.

Nếu bạn muốn hiểu "một bức tranh lớn" về cơ chế bố cục, hãy bắt đầu với cách tiếp cận bố cục của Flutter.

Bước 0: Tạo mã cơ sở ứng dụng

Đảm bảo thiết lập môi trường của bạn, sau đó thực hiện như sau:

  1. Tạo ứng dụng Flutter “Hello World” cơ bản.
  2. Thay đổi tiêu đề thanh ứng dụng và tiêu đề ứng dụng như sau:


lib/main.dart

@override
Widget build(BuildContext context) {
  return MaterialApp(
    title: 'Welcome to Flutter',
    title: 'Flutter layout demo',
    home: Scaffold(
      appBar: AppBar(
        title: Text('Welcome to Flutter'),
        title: Text('Flutter layout demo'),
      ),
      body: Center(
        child: Text('Hello World'),

Bước 1: Sơ đồ bố cục

Bước đầu tiên là chia nhỏ bố cục thành các yếu tố cơ bản của nó:

  • Xác định các hàng và cột.
  • Bố cục có bao gồm lưới không?
  • Có các yếu tố trùng lặp không?
  • Giao diện người dùng có cần tab không?
  • Lưu ý các khu vực yêu cầu căn chỉnh, đệm hoặc đường viền.

Đầu tiên, xác định các phần tử lớn hơn. Trong ví dụ này, bốn phần tử được sắp xếp thành một cột: một hình ảnh, hai hàng và một khối văn bản.

Phần tử cột (khoanh đỏ)
Phần tử cột (khoanh đỏ)

Tiếp theo, lập sơ đồ từng hàng. Hàng đầu tiên, được gọi là phần Tiêu đề, có 3 con: một cột văn bản, một biểu tượng ngôi sao và một số. Con đầu tiên của nó, cột, chứa 2 dòng văn bản. Cột đầu tiên đó chiếm nhiều dung lượng, vì vậy nó phải được bao bọc trong widget Expanded.

Phần tiêu đề
Hàng thứ hai, được gọi là phần Nút, cũng có 3 con: mỗi con là một cột chứa một biểu tượng và văn bản.
Phần nút

Khi bố cục đã được lập sơ đồ, cách dễ dàng nhất để thực hiện là tiếp cận từ dưới lên để triển khai nó. Để giảm thiểu sự nhầm lẫn trực quan của mã bố cục lồng nhau sâu, hãy đặt một số triển khai trong các biến và hàm.

Bước 2: Triển khai hàng tiêu đề

Đầu tiên, bạn sẽ xây dựng cột bên trái trong phần tiêu đề. Thêm mã sau vào đầu phương thức build() của lớp MyApp:

lib/main.dart (titleSection)
Widget titleSection = Container(
  padding: const EdgeInsets.all(32),
  child: Row(
    children: [
      Expanded(
        /*1*/
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            /*2*/
            Container(
              padding: const EdgeInsets.only(bottom: 8),
              child: Text(
                'Oeschinen Lake Campground',
                style: TextStyle(
                  fontWeight: FontWeight.bold,
                ),
              ),
            ),
            Text(
              'Kandersteg, Switzerland',
              style: TextStyle(
                color: Colors.grey[500],
              ),
            ),
          ],
        ),
      ),
      /*3*/
      Icon(
        Icons.star,
        color: Colors.red[500],
      ),
      Text('41'),
    ],
  ),
);

/*1*/ Đặt một widget Column bên trong widget Expanded để sử dụng tất cả không gian trống còn lại trong hàng. Đặt thuộc tính crossAxisAlignment thành CrossAxisAlignment.start để xác định vị trí cột ở đầu hàng.

/*2*/ Đặt hàng văn bản đầu tiên bên trong một Container để cho phép bạn thêm phần đệm. Con thứ hai trong Column, cũng là văn bản để hiển thị là màu xám.

/*3*/ Hai mục cuối cùng trong hàng tiêu đề là biểu tượng ngôi sao, sơn màu đỏ và văn bản "41". Toàn bộ hàng nằm trong một Container và được đệm dọc theo mỗi cạnh 32 pixel. Thêm phần tiêu đề vào nội dung ứng dụng như sau:

File /lib/main.dart:

return MaterialApp(
  title: 'Flutter layout demo',
  home: Scaffold(
    appBar: AppBar(
      title: Text('Flutter layout demo'),
    ),
    body: Center(
      child: Text('Hello World'),
      body: Column(
        children: [
          titleSection,
        ],
      ),
    ),
  );

Mẹo:

  • Khi dán mã vào ứng dụng của bạn, thụt lề có thể bị lệch. Bạn có thể sửa lỗi này trong trình chỉnh sửa Flutter của mình bằng cách sử dụng hỗ trợ định dạng lại tự động.
  • Để có trải nghiệm phát triển nhanh hơn, hãy thử tính năng tải lại nóng của Flutter.
  • Nếu bạn gặp sự cố, hãy so sánh mã của bạn với lib/main.dart.

Bước 3: Triển khai hàng nút

Phần nút chứa 3 cột sử dụng cùng một bố cục - một biểu tượng trên một hàng văn bản. Các cột trong hàng này cách đều nhau, văn bản và biểu tượng được sơn bằng màu chính.

Vì mã để xây dựng mỗi cột gần như giống nhau, bạn hãy tạo một phương thức trợ giúp riêng có tên buildButtonColumn(), phương thức này nhận một màu, một Icon và Text và trả về một cột với các widget con của nó được thể hiện bằng màu đã cho.

lib/main.dart (_buildButtonColumn)
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // ···
  }

  Column _buildButtonColumn(Color color, IconData icon, String label) {
    return Column(
      mainAxisSize: MainAxisSize.min,
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        Icon(icon, color: color),
        Container(
          margin: const EdgeInsets.only(top: 8),
          child: Text(
            label,
            style: TextStyle(
              fontSize: 12,
              fontWeight: FontWeight.w400,
              color: color,
            ),
          ),
        ),
      ],
    );
  }
}

Hàm sẽ có nhiệm vụ thêm biểu tượng trực tiếp vào cột. Văn bản nằm trong Container với lề chỉ trên cùng, ngăn cách văn bản với biểu tượng.

Xây dựng hàng chứa các cột này bằng cách gọi hàm và chuyển màu Icon, và văn bản cụ thể cho cột đó. Căn chỉnh các cột dọc theo trục chính bằng cách sử dụng MainAxisAlignment.spaceEvenly để sắp xếp không gian trống đồng đều trước, giữa và sau mỗi cột. Thêm mã sau ngay bên dưới khai báo titleSection bên trong phương thức build():

lib/main.dart (buttonSection)
Color color = Theme.of(context).primaryColor;

Widget buttonSection = Container(
  child: Row(
    mainAxisAlignment: MainAxisAlignment.spaceEvenly,
    children: [
      _buildButtonColumn(color, Icons.call, 'CALL'),
      _buildButtonColumn(color, Icons.near_me, 'ROUTE'),
      _buildButtonColumn(color, Icons.share, 'SHARE'),
    ],
  ),
);

Thêm phần nút vào nội dung:

/lib/main.dart
  return MaterialApp (
    title: 'Bản demo bố cục Flutter' ,
    home: Scaffold (
      body: Column(
        children: [
          titleSection,
          buttonSection,
        ],
      ),
    ),
  );
}

Bước 4: Triển khai phần văn bản

Xác định phần văn bản dưới dạng một biến. Đặt văn bản trong một Container và thêm phần đệm dọc theo mỗi cạnh. Thêm mã sau ngay bên dưới khai báo buttonSection:

lib/main.dart (textSection)
Widget textSection = Container(
  padding: const EdgeInsets.all(32),
  child: Text(
    'Lake Oeschinen lies at the foot of the Blüemlisalp in the Bernese '
        'Alps. Situated 1,578 meters above sea level, it is one of the '
        'larger Alpine Lakes. A gondola ride from Kandersteg, followed by a '
        'half-hour walk through pastures and pine forest, leads you to the '
        'lake, which warms to 20 degrees Celsius in the summer. Activities '
        'enjoyed here include rowing, and riding the summer toboggan run.',
    softWrap: true,
  ),
);

Bằng cách đặt softwrap thành true, các dòng văn bản sẽ lấp đầy chiều rộng cột trước khi bao quanh một ranh giới từ.

Thêm phần văn bản vào nội dung:

{step3 → step4} /lib/main.dart
return MaterialApp(   
  title: 'Flutter layout demo',
  home: Scaffold(
    children: [
      titleSection,
      buttonSection,
      textSection,   
    ],   
  ),
),

Bước 5: Thực hiện phần hình ảnh

Ba trong bốn phần tử cột hiện đã hoàn thành, chỉ còn lại hình ảnh. Thêm tệp hình ảnh vào ví dụ:

  • Tạo một thư mục images ở đầu dự án.
  • Thêm ảnh lake.jpg.

Lưu ý rằng wget không hoạt động để lưu tệp nhị phân này. Hình ảnh gốc có sẵn trực tuyến theo giấy phép Creative Commons, nhưng nó lớn và tải chậm.

  • Cập nhật file pubspec.yaml để bao gồm một thẻ assetsthẻ. Điều này làm cho hình ảnh có sẵn cho mã của bạn:
    /pubspec.yaml
    flutter:
      uses-material-design: true
      assets:
        images/lake.jpg

Mẹo:

  • Lưu ý là pubspec.yaml phân biệt chữ hoa và chữ thường nên cần viết là assets: và thể hiện URL hình ảnh phải như hình trên.
  • Tệp pubspec cũng nhạy cảm với khoảng trắng, vì vậy hãy sử dụng thụt lề thích hợp.

Bây giờ bạn có thể tham khảo hình ảnh từ đoạn mã của mình:

/lib/main.dart
),
body: Column(
  children: [
    Image.asset(
      'images/lake.jpg',
      width: 600,
      height: 240,
      fit: BoxFit.cover,
    ),
    titleSection,
    buttonSection,
    textSection,

BoxFit.cover cho framework biết rằng hình ảnh phải càng nhỏ càng tốt nhưng vẫn bao phủ toàn bộ hộp kết xuất của nó.

Bước 6: Lần chạm cuối cùng

Trong bước cuối cùng này, hãy sắp xếp tất cả các phần tử trong một ListView, thay vì một Column, bởi vì ListView hỗ trợ ứng dụng cuộn nội dung khi ứng dụng được chạy trên một thiết bị nhỏ.

/lib/main.dart
return MaterialApp(
  title: 'Flutter layout demo',
  home: Scaffold(
    appBar: AppBar(       
      title: Text('Flutter layout demo'),   
    ),
    body: Column(
      body: ListView(
        children: [
          Image.asset(
            'images/lake.jpg',
            width: 600,
            height: 240,
            fit: BoxFit.cover,

Code Dart: main.dart

Ảnh: images

Pubspec: pubspec.yaml

Đó là nó! Khi bạn tải lại nóng ứng dụng, bạn sẽ thấy bố cục ứng dụng giống như ảnh chụp màn hình ở đầu bài viết này.

Bạn có thể thêm tương tác vào bố cục này bằng cách xem bài viết Thêm tương tác vào ứng dụng Flutter của bạn.

Nguồn: flutter.dev
» Next: Flutter: Tạo ứng dụng đáp ứng
« Prev: Flutter: Layout (Bố cục) trong Flutter
Các khóa học qua video:
Python SQL Server PHP C# Lập trình C Java HTML5-CSS3-JavaScript
Học trên YouTube <76K/tháng. Đăng ký Hội viên
Copied !!!