Trang chủ Lập trình Flutter Flutter | Những nền tảng của ứng dụng Flutter/Layouts (bố cục)

Flutter | Những nền tảng của ứng dụng Flutter/Layouts (bố cục)

710
0

Bài viết này mình sẽ trình bày về bố cục, một trong những nền tảng của ứng dụng Flutter

Bố cục trong Flutter

Khái niệm chính của cơ chế bố trí là widget con. Chúng tâ biết rằng flutter giả định mọi thứ như một widget. Vì vậy, hình ảnh, biểu tượng, văn bản và thậm chí cả bố cục của ứng dụng của bạn đều là widget. Ở đây, một số thứ bạn không thấy trên giao diện người dùng ứng dụng của mình, chẳng hạn như các hàng, cột và lưới sắp xếp, ràng buộc và căn chỉnh các widget con hiển thị cũng là các widget con. Flutter cho phép chúng ta tạo bố cục bằng cách soạn nhiều widget để xây dựng các widget phức tạp hơn. Ví dụ, chúng ta có thể thấy hình ảnh dưới đây hiển thị ba biểu tượng với nhãn bên dưới mỗi biểu tượng.

Trong hình ảnh thứ hai, chúng ta có thể thấy bố cục trực quan của hình ảnh trên. Hình ảnh này hiển thị một hàng gồm ba cột và các cột này chứa một biểu tượng và nhãn.

Trong hình trên, vùng chứa là một lớp widget cho phép chúng ta tùy chỉnh widget con. Nó chủ yếu được sử dụng để thêm đường viền, đệm, lề, màu nền và nhiều thứ khác. Tại đây, widget văn bản nằm dưới vùng chứa để thêm lề. Toàn bộ hàng cũng được đặt trong một vùng chứa để thêm lề và phần đệm xung quanh hàng. Ngoài ra, phần còn lại của giao diện người dùng được kiểm soát bởi các thuộc tính như màu sắc, kiểu văn bản, v.v.

Bố trí một widget

Chúng ta sẽ tìm hiểu cách có thể tạo và hiển thị một widget đơn giản. Các bước sau đây cho biết cách bố trí một widget:

Bước 1: Đầu tiên, bạn cần chọn một bố cục của widget.

Bước 2: Tiếp theo, tạo một widget hiển thị.

Bước 3: Sau đó, thêm widget hiển thị vào widget bố cục.

Bước 4: Cuối cùng, thêm widget bố cục vào trang mà bạn muốn hiển thị.

Các loại bố cục widget

Chúng ta có thể phân loại bố cục widget thành hai loại:

– Widget con đơn

– Nhiều Widget con

1. Các widget con đơn

Widget bố cục con duy nhất là một loại tiện ích con, có thể chỉ có một tiện ích con bên trong tiện ích bố cục mẹ. Các widget này cũng có thể chứa chức năng bố cục đặc biệt. Flutter cung cấp cho chúng ta nhiều widget con để làm cho giao diện người dùng của ứng dụng trở nên hấp dẫn. Nếu chúng ta sử dụng các widget này một cách thích hợp, nó có thể tiết kiệm thời gian của chúng ta và làm cho mã ứng dụng dễ đọc hơn. Danh sách các loại widget con đơn lẻ khác nhau là:

Vùng chứa (container): Đây là widget bố cục phổ biến nhất cung cấp các tùy chọn có thể tùy chỉnh để vẽ, định vị và định cỡ các widget.





Padding: Nó là một widget được sử dụng để sắp xếp widget con của nó theo khoảng đệm đã cho. Nó chứa EdgeInsets và EdgeInsets.fromLTRB cho phía mong muốn mà bạn muốn cung cấp đệm.

const Greetings(  

  child: Padding(  

    padding: EdgeInsets.all(14.0),  

    child: Text('Hello JavaTpoint!'),  

  ),  

)

Trung tâm: widget con này cho phép bạn căn giữa widget con trong chính nó.

Căn chỉnh: Đây là một widget con, căn chỉnh widget con của nó trong chính nó và định kích thước nó dựa trên kích thước của lớp sau. Nó cung cấp nhiều quyền kiểm soát hơn để đặt tiện ích con ở vị trí chính xác mà bạn cần.

Center(  

  child: Container(  

    height: 110.0,  

    width: 110.0,  

    color: Colors.blue,  

    child: Align(  

      alignment: Alignment.topLeft,  

      child: FlutterLogo(  

        size: 50,  

      ),  

    ),  

  ),  

)

SizedBox: Widget này cho phép bạn cung cấp kích thước được chỉ định cho widget con thông qua tất cả các màn hình.

SizedBox(  

  width: 300.0,  

  height: 450.0,  

  child: const Card(child: Text('Hello JavaTpoint!')),  

)

AspectRatio: widget này cho phép bạn giữ kích thước của widget con theo một tỷ lệ khung hình được chỉ định.

AspectRatio(  

  aspectRatio: 5/3,  

  child: Container(  

    color: Colors.bluel,  

  ),  

),

Baseline: widget này thay đổi widget con theo đường cơ sở của lớp sau.

child: Baseline(  

         baseline: 30.0,  

         baselineType: TextBaseline.alphabetic,  

         child: Container(  

              height: 60,  

              width: 50,  

              color: Colors.blue,  

         ),  

)

ConstrainedBox: Đây là một widget cho phép bạn buộc các ràng buộc bổ sung trên widget con của nó. Nó có nghĩa là bạn có thể buộc widget con có một ràng buộc cụ thể mà không làm thay đổi các thuộc tính của widget con.

ConstrainedBox(  

  constraints: new BoxConstraints(  

    minHeight: 150.0,  

    minWidth: 150.0,  

    maxHeight: 300.0,  

    maxWidth: 300.0,  

  ),  

  child: new DecoratedBox(  

    decoration: new BoxDecoration(color: Colors.red),  

  ),  

),

CustomSingleChildLayout: Nó là một widget, chuyển từ bố cục của con đơn thành một đại biểu. Người được ủy quyền quyết định vị trí của widget con và cũng được sử dụng để xác định kích thước của widget con.

FittedBox: Nó chia tỷ lệ và định vị widget con theo sự phù hợp được chỉ định.

import 'package:flutter/material.dart';  

void main() => runApp(MyApp());  

class MyApp extends StatelessWidget {  

  // It is the root widget of your application.  

  @override  

  Widget build(BuildContext context) {  

    return MaterialApp(  

      title: 'Multiple Layout Widget',  

      debugShowCheckedModeBanner: false,  

      theme: ThemeData(  

        // This is the theme of your application.  

        primarySwatch: Colors.green,  

      ),  

      home: MyHomePage(),  

    );  

  }  

}  

class MyHomePage extends StatelessWidget {  

  @override  

  Widget build(BuildContext context) {  

    return Scaffold(  

        appBar: AppBar(title: Text("FittedBox Widget")),  

        body: Center(  

        child: FittedBox(child: Row(  

          children: <Widget>[  

            Container(  

              child: Image.asset('assets/computer.png'),  

              ),  

              Container(  

                child: Text("This is a widget"),  

              )  

            ],  

          ),  

          fit: BoxFit.contain,  

        )  

      ),  

    );  

  }  

}

Output

FractionallySizedBox: Nó là một widget cho phép kích thước của widget con của nó theo phần nhỏ của không gian có sẵn.

 IntrinsicHeight and IntrinsicWidth: Chúng là một widget con cho phép chúng ta định kích thước widget con của nó theo chiều cao và chiều rộng nội tại của lớp sau.

LimitedBox: widget này chỉ cho phép chúng ta giới hạn kích thước của nó khi nó không bị giới hạn.

Offstage: Nó được sử dụng để đo kích thước của một widget mà không cần đưa nó lên màn hình.

OverflowBox: Đây là một widget, cho phép áp đặt các ràng buộc khác nhau đối với widget con của nó so với các ràng buộc mà nó nhận được từ lớp trước. Nói cách khác, nó cho phép widget con làm tràn widget lớp trước.

Thí dụ

import 'package:flutter/material.dart';  

void main() => runApp(MyApp());  

class MyApp extends StatelessWidget {  

  // It is the root widget of your application.  

  @override  

  Widget build(BuildContext context) {  

    return MaterialApp(  

      title: 'Single Layout Widget',  

      debugShowCheckedModeBanner: false,  

      theme: ThemeData(  

        // This is the theme of your application.  

        primarySwatch: Colors.blue,  

      ),  

      home: MyHomePage(),  

    );  

  }  

}  

class MyHomePage extends StatelessWidget {  

  @override  

  Widget build(BuildContext context) {  

    return Scaffold(  

      appBar: AppBar(  

        title: Text("OverflowBox Widget"),  

      ),  

      body: Center(  

      child: Container(  

        height: 50.0,  

        width: 50.0,  

        color: Colors.red,  

        child: OverflowBox(  

          minHeight: 70.0,  

          minWidth: 70.0,  

          child: Container(  

            height: 50.0,  

            width: 50.0,  

            color: Colors.blue,  

            ),  

          ),  

        ),  

      ),  

    );  

  }  

}

Output

2. Nhiều widget con

Nhiều widget con là một loại widget chứa nhiều hơn một widget con và cách bố trí của các widget này là duy nhất. Ví dụ: widget con Hàng bố trí widget con theo hướng ngang và widget Cột bố trí widget con theo hướng dọc. Nếu chúng ta kết hợp widget con Hàng và Cột, thì nó có thể xây dựng bất kỳ cấp độ nào của widget con phức tạp.

Ở đây, chúng ta sẽ tìm hiểu các loại khác nhau của nhiều widget con:

Row: Nó cho phép sắp xếp các widget con của nó theo hướng nằm ngang.

Thí dụ

import 'package:flutter/material.dart';  

void main() => runApp(MyApp());  

class MyApp extends StatelessWidget {  

  // It is the root widget of your application.  

  @override  

  Widget build(BuildContext context) {  

    return MaterialApp(  

      title: 'Multiple Layout Widget',  

      debugShowCheckedModeBanner: false,  

      theme: ThemeData(  

        // This is the theme of your application.  

        primarySwatch: Colors.blue,  

      ),  

      home: MyHomePage(),  

    );  

  }  

}  

class MyHomePage extends StatelessWidget {  

  @override  

  Widget build(BuildContext context) {  

    return Center(  

      child: Container(  

        alignment: Alignment.center,  

        color: Colors.white,  

        child: Row(  

          children: <Widget>[  

            Expanded(  

              child: Text('Peter', textAlign: TextAlign.center),  

            ),  

            Expanded(  

              child: Text('John', textAlign: TextAlign.center ),  

            ),  

            Expanded(  

              child: FittedBox(  

                fit: BoxFit.contain, // otherwise the logo will be tiny  

                child: const FlutterLogo(),  

              ),  

            ),  

          ],  

        ),  

      ),  

    );  

  }  

}

Output

Column: Nó cho phép sắp xếp các widget con của nó theo hướng dọc.

ListView: Đây là widget cuộn phổ biến nhất cho phép chúng ta sắp xếp các widget con của nó lần lượt theo hướng cuộn.

GridView: Nó cho phép chúng ta sắp xếp các widget con của nó dưới dạng một mảng widget 2D, có thể cuộn được. Nó bao gồm một mô hình lặp lại của các ô được sắp xếp theo bố cục ngang và dọc.

Expanded: Nó cho phép tạo các con của widget con Hàng và Cột chiếm diện tích tối đa có thể.

Table:  Nó là một widget cho phép chúng ta sắp xếp các con của nó trong một widget dựa trên bảng.

Flow: Nó cho phép chúng ta triển khai widget dựa trên luồng.

Stack: Đây là một widget thiết yếu, chủ yếu được sử dụng để chồng chéo một số widget con. Nó cho phép bạn đặt nhiều lớp lên màn hình.

Ví dụ sau đây giúp bạn hiểu nó.

import 'package:flutter/material.dart';  

void main() => runApp(MyApp());  

class MyApp extends StatelessWidget {  

  // It is the root widget of your application.  

  @override  

  Widget build(BuildContext context) {  

    return MaterialApp(  

      title: 'Multiple Layout Widget',  

      debugShowCheckedModeBanner: false,  

      theme: ThemeData(  

        // This is the theme of your application.  

        primarySwatch: Colors.blue,  

      ),  

      home: MyHomePage(),  

    );  

  }  

}  

class MyHomePage extends StatelessWidget {  

  @override  

  Widget build(BuildContext context) {  

    return Center(  

      child: Container(  

        alignment: Alignment.center,  

        color: Colors.white,  

        child: Stack(  

          children: <Widget>[  

            // Max Size  

            Container(  

              color: Colors.blue,  

            ),  

            Container(  

              color: Colors.pink,  

              height: 400.0,  

              width: 300.0,  

            ),  

            Container(  

              color: Colors.yellow,  

              height: 220.0,  

              width: 200.0,  

            )  

          ],  

        ),  

      ),  

    );  

  }  

}

Output

Xây dựng bố cục phức tạp

Trong phần này, chúng ta sẽ tìm hiểu cách bạn có thể tạo giao diện người dùng phức tạp bằng cách sử dụng cả widget con bố cục đơn và nhiều widget con. Khung bố cục cho phép bạn tạo bố cục giao diện người dùng phức tạp bằng cách lồng các hàng và cột vào bên trong các hàng và cột.

chúng ta xem một ví dụ về giao diện người dùng phức tạp bằng cách tạo danh sách sản phẩm. Với mục đích này, trước tiên bạn cần thay thế mã của tệp main.dart bằng đoạn mã sau.

import 'package:flutter/material.dart';  

void main() => runApp(MyApp());  

class MyApp extends StatelessWidget {  

  // It is the root widget of your application.  

  @override  

  Widget build(BuildContext context) {  

    return MaterialApp(  

      title: 'Flutter Demo Application', theme: ThemeData(  

      primarySwatch: Colors.green,),  

      home: MyHomePage(title: 'Complex layout example'),  

    );  

  }  

}  

class MyHomePage extends StatelessWidget {  

  MyHomePage({Key key, this.title}) : super(key: key);  

  final String title;  

  @override  

  Widget build(BuildContext context) {  

    return Scaffold(  

        appBar: AppBar(title: Text("Product List")),  

        body: ListView(  

          padding: const EdgeInsets.fromLTRB(3.0, 12.0, 3.0, 12.0),  

          children: <Widget>[  

            ProductBox(  

                name: "iPhone",  

                description: "iPhone is the top branded phone ever",  

                price: 55000,  

                image: "iphone.png"  

            ),  

            ProductBox(  

                name: "Android",  

                description: "Android is a very stylish phone",  

                price: 10000,  

                image: "android.png"  

            ),  

            ProductBox(  

                name: "Tablet",  

                description: "Tablet is a popular device for official meetings",  

                price: 25000,  

                image: "tablet.png"  

            ),  

            ProductBox(  

                name: "Laptop",  

                description: "Laptop is most famous electronic device",  

                price: 35000,  

                image: "laptop.png"  

            ),  

            ProductBox(  

                name: "Desktop",  

                description: "Desktop is most popular for regular use",  

                price: 10000,  

                image: "computer.png"  

            ),  

          ],  

        )  

    );  

  }  

}  

class ProductBox extends StatelessWidget {  

  ProductBox({Key key, this.name, this.description, this.price, this.image}) :  

        super(key: key);  

  final String name;  

  final String description;  

  final int price;  

  final String image;  

  Widget build(BuildContext context) {  

    return Container(  

        padding: EdgeInsets.all(2),  

        height: 110,  

        child: Card(  

            child: Row(  

                mainAxisAlignment: MainAxisAlignment.spaceEvenly,  

                children: <Widget>[  

                  Image.asset("assets/" + image),  

                  Expanded(  

                      child: Container(  

                          padding: EdgeInsets.all(5),  

                          child: Column(  

                            mainAxisAlignment: MainAxisAlignment.spaceEvenly,  

                            children: <Widget>[  

                              Text(  

                                  this.name, style: TextStyle(  

                                  fontWeight: FontWeight.bold  

                              )  

                              ),  

                              Text(this.description), Text(  

                                  "Price: " + this.price.toString()  

                              ),  

                            ],  

                          )  

                      )  

                  )  

                ]  

            )  

        )  

    );  

  }  

}

Trong đoạn mã trên, chúng ta tạo ProductBox widget chứa các thông tin chi tiết của sản phẩm, chẳng hạn như hình ảnh, tên, giá và mô tả. Trong widget ProductBox, chúng tôi sử dụng các widget con sau: Vùng chứa, Hàng, Cột, Mở rộng, Thẻ, Văn bản, Hình ảnh, v.v. Widget này có bố cục sau:

Output

Bây giờ, khi chúng ta chạy tệp dart trong trình giả lập Android, nó sẽ cho kết quả như sau.

Cuối cùng

Cám ơn bạn đã theo dõi bài viết về bố cục trong Flutter, ngoài ra các bạn có thể xem thêm các nội dung khác trong chuyên mục lập trình Flutter được chia sẻ bởi Nguyễn Hưng.

BÌNH LUẬN

Vui lòng nhập bình luận của bạn
Vui lòng nhập tên của bạn ở đây

Website này sử dụng Akismet để hạn chế spam. Tìm hiểu bình luận của bạn được duyệt như thế nào.