Ngăn xếp(Stack) là một widget trong Flutter chứa danh sách các widget và đặt chúng trên đầu các widget khác. Nói cách khác, ngăn xếp cho phép các nhà phát triển chồng nhiều widget vào một màn hình duy nhất và hiển thị chúng từ dưới lên trên. Do đó, widget đầu tiên là mục dưới cùngwidget cuối cùng là mục trên cùng

1. Các điểm chính liên quan đến Stack Widget

Sau đây là những điểm chính của widget ngăn xếp Flutter :

  • widget trong ngăn xếp có thể được định vị hoặc không được định vị .
  • Các mục được định vị được bao bọc trong widget được Định vị và phải có một thuộc tính không rỗng
  • Các widget con không định vị được tự căn chỉnh. Nó hiển thị trên màn hình dựa trên sự liên kết của ngăn xếp. Vị trí mặc định của các con là ở góc trên cùng bên trái.
  • Chúng ta có thể sử dụng thuộc tính alignment để thay đổi sự liên kết của các widget.
  • Stack đặt các widget con theo thứ tự với con đầu tiên ở dưới cùng và con cuối cùng ở trên cùng. Nếu chúng ta muốn sắp xếp lại widget dành cho trẻ em, thì bắt buộc phải xây dựng lại ngăn xếp theo thứ tự mới. Theo mặc định, widget đầu tiên của mỗi ngăn xếp có kích thước tối đa so với các widget khác.

3. Làm thế nào để sử dụng một widget ngăn xếp trong Flutter?

Ví dụ dưới đây giúp hiểu nhanh việc sử dụng widget ngăn xếp có chứa ba vùng chứa có kích thước thu nhỏ:

Stack(  
  children: <Widget>[  
    // Max Size  
    Container(  
      color: Colors.green,  
    ),  
    Container(  
      color: Colors.blue,  
    ),  
    Container(  
      color: Colors.yellow,  
    )  
  ],  
),  

Nó sẽ cho kết quả sau:

4. Thuộc tính của widget ngăn xếp

Sau đây là các thuộc tính được sử dụng với widget ngăn xếp:

alignment: Nó xác định cách các widget được định vị trong ngăn xếp. Nó có thể là trên cùng, dưới cùng, giữa, giữa bên phải, v.v.

Stack(  
  alignment: Alignment.topCenter, // Center of Top  
  children: <Widget>[ ]  
)  

textDirection : Nó xác định hướng văn bản. Nó có thể vẽ văn bản ltr (từ trái sang phải) hoặc rtl (từ phải sang trái).

Stack(  
  textDirection: TextDirection.rtl, // Right to Left  
  children: <Widget>[ ]  
)  

fit: Nó sẽ kiểm soát kích thước của các widget không được định vị trong ngăn xếp. Nó có ba loại: lloose, expand and passthrough. Thuộc tính lỏng lẻo được sử dụng để đặt widget nhỏ, thuộc tính expand làm cho widget càng lớn càng tốt và passthrough đặt widget tùy thuộc vào widget của nó.

Stack(  
  fit: StackFit.passthrough,  
  children: <Widget>[ ]  
)  

overflow : Nó kiểm soát các widget con, cho dù hiển thị hay bị cắt bớt, khi nội dung của nó tràn ra bên ngoài ngăn xếp.

Stack(  
  overflow: Overflow.clip, // Clip the Content  
  children: <Widget>[ ]  
)  

clipBehavior : Nó xác định nội dung có được cắt bớt hay không.

5. Định vị(Positioned)

Nó không phải là tham số ngăn xếp nhưng có thể được sử dụng trong ngăn xếp để định vị các widget con. Sau đây là hàm tạo của ngăn xếp được định vị:

const Positioned({  
Key key,  
this.left,  
this.top,  
this.right,  
this.bottom,  
this.width,  
this.height,  
@required Widget child,  
})   

6. Ví dụ về widget ngăn xếp

Đoạn mã dưới đây giải thích cách sử dụng widget ngăn xếp trong Flutter . Trong đoạn mã này, chúng ta sẽ thử hầu hết các thuộc tính thiết yếu của widget ngăn xếp.

import 'package:flutter/material.dart';  
  
void main() => runApp(MyApp());  
  
/// This Widget is the main application widget.  
class MyApp extends StatelessWidget {  
  @override  
  Widget build(BuildContext context) {  
    return MaterialApp(  
      home: MyStackWidget(),  
    );  
  }  
}  
  
class MyStackWidget extends StatelessWidget {  
  @override  
  Widget build(BuildContext context) {  
    return MaterialApp(  
      home: Scaffold(  
        appBar: AppBar(  
          title: Text("Flutter Stack Widget Example"),  
        ),  
        body: Center(  
          child: Stack(  
            fit: StackFit.passthrough,  
            overflow: Overflow.visible,  
            children: <Widget>[  
              // Max Size Widget  
              Container(  
                height: 300,  
                width: 400,  
                color: Colors.green,  
                child: Center(  
                  child: Text(  
                    'Top Widget: Green',  
                    style: TextStyle(color: Colors.white, fontSize: 20),  
                  ),  
                ),  
              ),  
              Positioned(  
                top: 30,  
                right: 20,  
                child: Container(  
                  height: 100,  
                  width: 150,  
                  color: Colors.blue,  
                  child: Center(  
                    child: Text(  
                      'Middle Widget',  
                      style: TextStyle(color: Colors.white, fontSize: 20),  
                    ),  
                  ),  
                ),  
              ),  
              Positioned(  
                top: 30,  
                left: 20,  
                child: Container(  
                  height: 100,  
                  width: 150,  
                  color: Colors.orange,  
                  child: Center(  
                    child: Text(  
                      'Bottom Widget',  
                      style: TextStyle(color: Colors.white, fontSize: 20),  
                    ),  
                  ),  
                )  
              ),  
            ],  
          ),  
        )  
      ),  
    );  
  }  
} 

Đầu ra:

Khi chúng ta chạy ứng dụng, chúng tôi sẽ nhận được giao diện người dùng của màn hình tương tự như ảnh chụp màn hình bên dưới:

7. Flutter IndexedStack

Nó là một widget ngăn xếp khác trong Flutter chỉ hiển thị một phần tử tại một thời điểm bằng cách chỉ định chỉ mục của nó . Xem đoạn code dưới đây:

IndexedStack(  
  index: 1,  
  children: <Widget>[  
    Container(  
      color: Colors.green,  
    ),  
    Container(  
      color: Colors.blue,  
    ),  
    Container(  
      color: Colors.yellow,  
    )  
  ],  
)  

IndexedStack nhận các widget con giống như một ngăn xếp thông thường, nhưng nó sẽ chỉ hiển thị một con tại một thời điểm. Do đó, nó không phải là một ngăn xếp. Chúng ta sử dụng nó để dễ dàng chuyển đổi giữa child này sang child khác theo nhu cầu của chúng ta.

8. Ví dụ về widget IndexedStack

Đoạn mã dưới đây giải thích cách sử dụng widget ngăn xếp được lập chỉ mục trong Flutter:

import 'package:flutter/material.dart';  
  
void main() => runApp(MyApp());  
  
/// This Widget is the main application widget.  
class MyApp extends StatelessWidget {  
  @override  
  Widget build(BuildContext context) {  
    return MaterialApp(  
      home: MyStackWidget(),  
    );  
  }  
}  
  
class MyStackWidget extends StatelessWidget {  
  @override  
  Widget build(BuildContext context) {  
    return MaterialApp(  
      home: Scaffold(  
        appBar: AppBar(  
          title: Text("Flutter Stack Widget Example"),  
        ),  
        body: Center(  
          child: IndexedStack(  
            index: 0,  
            children: <Widget>[  
              Container(  
                height: 300,  
                width: 400,  
                color: Colors.green,  
                child: Center(  
                  child: Text(  
                    'First Widget',  
                    style: TextStyle(color: Colors.white, fontSize: 20),  
                  ),  
                ),  
              ),  
              Container(  
                height: 250,  
                width: 250,  
                color: Colors.blue,  
                child: Center(  
                  child: Text(  
                    'Second Widget',  
                    style: TextStyle(color: Colors.white, fontSize: 20),  
                  ),  
                ),  
              ),  
            ],  
          ),  
        )  
      ),  
    );  
  }  
} 

Đầu ra:

Khi chúng ta chạy ứng dụng, chúng tôi sẽ nhận được giao diện người dùng của màn hình tương tự như ảnh chụp màn hình bên dưới:

9. Có thể bọc ngăn xếp bên trong ngăn xếp trong Flutter không?

Có, có thể bọc ngăn xếp bên trong ngăn xếp trong Flutter. Chúng ta có thể làm điều này bằng cách bao bọc ngăn xếp thứ hai bên trong vùng chứa với thuộc tính chiều cao và chiều rộng.

Xem đoạn code dưới đây để hiểu rõ hơn:

import 'package:flutter/material.dart';  
  
void main() => runApp(MyApp());  
  
class MyApp extends StatelessWidget {  
  @override  
  Widget build(BuildContext context) {  
    return MaterialApp(  
      home: MyStackWidget(),  
    );  
  }  
}  
  
class MyStackWidget extends StatelessWidget {  
  @override  
  Widget build(BuildContext context) {  
    return MaterialApp(  
      home: Scaffold(  
        appBar: AppBar(  
          title: Text("Flutter Stack Widget Example"),  
        ),  
        body: Center(  
          child: Stack(  
            children: [  
              Positioned(  
                top: 100,  
                child: Text(  
                    "Stack#1",  
                    style: TextStyle(color: Colors.black, fontSize: 20)  
                ),  
              ),  
              Positioned(  
                top: 150.0,  
                child: Container(  
                  height: 220,  
                  width: 220,  
                  color: Colors.green,  
                  child: Stack(  
                    children: [  
                      Positioned(  
                        top:160,  
                        child: Text(  
                          "Stack Inside Stack#1",  
                          style: TextStyle(color: Colors.white, fontSize: 20)  
                        ),  
                      )  
                    ],  
                  ),  
                ),  
              )  
            ],  
          ),  
        )  
      ),  
    );  
  }  
}  

Khi chúng ta chạy ứng dụng, chúng ta sẽ nhận được giao diện người dùng của màn hình tương tự như ảnh chụp màn hình bên dưới:

Cài ứng dụng cafedev để dễ dàng cập nhật tin và học lập trình mọi lúc mọi nơi tại đây.

Tài liệu từ cafedev:

Nếu bạn thấy hay và hữu ích, bạn có thể tham gia các kênh sau của cafedev để nhận được nhiều hơn nữa:

Chào thân ái và quyết thắng!

Đăng ký kênh youtube để ủng hộ Cafedev nha các bạn, Thanks you!