Loading Now

Tạo Ứng Dụng iOS Và Android Với Flutter (Phần 2)

Trong phần trước mình đã giới thiệu cơ bản về widget trong flutter để tạo ra 1 ứng dụng trên ios hay android. Phần này mình sẽ hướng dẫn các bạn về cách xây dựng bố cục trong flutter.

Building layouts

1. Layouts in Flutter (Bố cục trong Flutter)

  • Widgets là các classes được sử dụng để xây dựng UIs.
  • Widgets được sử dụng cho cả 2 yếu tố là Layout và UI (giao diện người dùng).
  • Từ các widgets cơ bản có thể customize (tùy chỉnh) thành các widgets phức tạp hơn.
  • Cốt lõi của cơ chế thiết kế bố cục trong Flutter là Widgets. Images, icons, text, .. đều là widgets.
  • Dưới đây là sơ đồ cây widgets trong Flutter :

  • Container là 1 widget cho phép bạn tùy chỉnh widget con của nó. Sử dụng Container khi bạn muốn padding, margin, borders, hoặc background color.

a. Lay out a widget (bố cục 1 widget)

  • Lựa chọn widget : bạn có thể lựa chọn 1 widget theo mong muốn, truy cập layout widgets. Căn chỉnh và chứa các visible widget (widget hiển thị)
  • Tạo và hiển thị widget (visible widget):
    • Text(‘Hello World’)
    • Image.asset(‘image/lake.jpg’, fit: BoxFit.cover)
    • Icon(Icons.star, color: Colors.red[500])
  • Tạo và hiển thị widget (visible widget) trong bố cục widget (layout widget)
    • Center( child : Text(‘Hello World’))
  • Thêm bố cục layout (layout widget) tới trang hiển thị
    • Material apps : bạn có thể sử dụng Staffold widget, nó cung cấp 1 banner mặc định, background color, và có API cho việc them drawers, snack bars và bottom sheets. Sau đó bạn có thể them Center widget và body.
    • 	class MyApp extends StatelessWidget {
      	  @override
      	  Widget build(BuildContext context) {
      	    return MaterialApp(
      	      title: 'Flutter layout demo',
      	      home: Scaffold(
      	        appBar: AppBar(
      	          title: Text('Flutter layout demo'),
      	        ),
      	        body: Center(
      	          child: Text('Hello World'),
      	        ),
      	      ),
      	    );
      	  }
      	}
    • Lưu ý rằng : thư viện Material được kế thừa từ Material Desing. Khi thiết kế UI bạn có thể sử dụng tiêu chuẩn widgets library hoặc bạn có thể sử dụng các widget từ Material library.
    • Non-Material app : khi bạn không sử dụng Material apps thì sẽ không bao gồm AppBar, title, background color. Mà chúng ta sẽ phải code chay để tạo ra nó.

b. Lay out multiple widgets vertically and horizontally (bố cục layout theo chiều ngang và chiều dọc)

  • Một trong các bố cục phổ biến nhất trong Flutter là sắp xếp các widget theo chiều ngang và chiều dọc.
  • Row và Column là 2 bố cục được sử dụng phổ biến.
  • Tạo 1 hàng hoặc 1 cột trong Flutter, bạn them 1 danh sách các widgets vào widget row và column.

  • Cột con bên trái được lồng các hang và cột bên trong :

  • Lưu ý : Row và Column là 2 widget cơ bản cho bố cục ngang và dọc. Không dừng lại ở đó, để thuận tiện cho việc design, bạn cũng có thể sử dụng ListTile – hiển thị item rất tiện lợi và bạn cũng có thể thay thế ListView cho Column tạo bố cục cuộc đẹp và linh hoạt hơn.

c. Aligning widgets (căn chỉnh các widgets)

  • Căn chỉnh các hang và cột con của row và column bằng cách sử dụng thuộc thính mainAxisAlignment và crossAxisAlignment. Đối với hang, trục chính theo chiều ngang và trục chéo theo chiều dọc. Còn với cột, trục chính theo chiều dọc và trục chéo theo chiều ngang.

  • Lớp MainAxisAlignment và CrossAxisAlignment cung cấp nhiều hằng số để kiểm soát việc căn chỉnh các item con trong row và column.

d. Sizing widgets (kích thước widgets)

  • Chắc hẳn các bạn khi thiết kế ít nhiều đều gặp trường hợp kích thước layout quá lớn để hiển thị lên thiết bị, vậy phải làm như nào để có thể thiết kế vừa vặn với device.
  • Layout widgets cung cấp 1 class là Expanded – điều chỉnh kích thước vừa trong 1 hàng hoặc cột.
	Row(
	  crossAxisAlignment: CrossAxisAlignment.center,
	  children: [
	    Expanded(
	      flex: 1,
	      child: Image.asset('images/pic1.jpg'),
	    ),
	    Expanded(
	      flex: 1,
	      child: Image.asset('images/pic2.jpg'),
	    ),
	    Expanded(
	      flex: 1,
	      child: Image.asset('images/pic3.jpg'),
	    ),
	  ],
	);
  • Hãy sử dụng flex để xác định số phần mà widget chiếm trên toàn bộ chiều dài hoặc chiều cao của row hoặc column.
  • Như ở ví dụ trên thì mỗi tấm ảnh hiển thị chiếm 1 phần, nghĩa là 3 phần chia đều cho từng tấm ảnh.

e. Packing widgets

  • Theo mặc định, một hang hoặc một cột chiếm càng nhiều không gian dọc theo trục chính của nó càng tốt nhưng nếu bạn muốn packing(hình thức đóng gói) các thành phần con lại lần nhau hãy sử dụng mainAxisSize với giá trị là MainAxisSize.min

f. Nesting rows and columns (lồng các cột các hang với nhau)

  • Layout framework cho phép bạn lồng các hang và cột bên trong các hang và cột khi bạn cần thiết.

  • Phần bôi đỏ, hiển thị 2 hàng : hang xếp hạng chứ 5 ngồi sao và số lượng đánh giá và hang biểu tượng chứ 3 cột biểu tượng và văn bản.
  • Chúng ta sẽ xây dựng cây widget cho hang 1 như sau :

var stars = Row(
  mainAxisSize: MainAxisSize.min,
  children: [
    Icon(Icons.star, color: Colors.green[500]),
    Icon(Icons.star, color: Colors.green[500]),
    Icon(Icons.star, color: Colors.green[500]),
    Icon(Icons.star, color: Colors.black),
    Icon(Icons.star, color: Colors.black),
  ],
);

final ratings = Container(
  padding: EdgeInsets.all(20),
  child: Row(
    mainAxisAlignment: MainAxisAlignment.spaceEvenly,
    children: [
      stars,
      Text(
        '170 Reviews',
        style: TextStyle(
          color: Colors.black,
          fontWeight: FontWeight.w800,
          fontFamily: 'Roboto',
          letterSpacing: 0.5,
          fontSize: 20,
        ),
      ),
    ],
  ),
);
  • Và đây là cây widget cho hang thứ 2 :

final descTextStyle = TextStyle(
  color: Colors.black,
  fontWeight: FontWeight.w800,
  fontFamily: 'Roboto',
  letterSpacing: 0.5,
  fontSize: 18,
  height: 2,
);

// DefaultTextStyle.merge() allows you to create a default text
// style that is inherited by its child and all subsequent children.
final iconList = DefaultTextStyle.merge(
  style: descTextStyle,
  child: Container(
    padding: EdgeInsets.all(20),
    child: Row(
      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
      children: [
        Column(
          children: [
            Icon(Icons.kitchen, color: Colors.green[500]),
            Text('PREP:'),
            Text('25 min'),
          ],
        ),
        Column(
          children: [
            Icon(Icons.timer, color: Colors.green[500]),
            Text('COOK:'),
            Text('1 hr'),
          ],
        ),
        Column(
          children: [
            Icon(Icons.restaurant, color: Colors.green[500]),
            Text('FEEDS:'),
            Text('4-6'),
          ],
        ),
      ],
    ),
  ),
);

Tạm kết

Layout trong Flutter rất đa dạng và phong phú. Nó là sự kết hợp giữa Material Design (Android) và Cupertino (Ios) vì thế nó trở nên linh hoạt và tiện dụng. Phần tiếp theo mình sẽ tiếp tục chia sẻ cho các bạn về UI trong Flutter. Mình sẽ cố gắng demo các Widget cần thiết nhất để các bạn có thể nắm rõ hơn. Hãy đón nhận các bài viết tiếp theo của mình nhé !!!

Post Comment

Contact