Thêm tương tác vào ứng dụng Flutter của bạn (Phần 2)

Ở phần trước, ta có đề cập đến Stateful và Stateless widgets. Vậy chúng là gì? Ta sẽ cùng tìm hiểu ở phần này

Stateful và stateless widgets

Một widget có thể có trạng thái hoặc không. Nếu một widget có thể thay đổi, ví dụ như khi người dùng tương tác với nó, thì đó là có trạng thái.

Một widget không trạng thái không bao giờ thay đổi. Icon , IconButton và Text là những ví dụ về các widget không trạng thái. Các widget phi trạng thái extends từ StatelessWidget.

Một widget có trạng thái là động: ví dụ, nó có thể thay đổi giao diện của nó để đáp ứng với các sự kiện được kích hoạt bởi tương tác của người dùng hoặc khi nhận được dữ liệu. Checkbox, Radio, Slider, InkWell , Form và TextField là những ví dụ về các widget có trạng thái. Các widget này extends StatefulWidget .

Trạng thái của widget được lưu trữ trong một đối tượng State, tách biệt trạng thái của widget khỏi sự xuất hiện của nó. Trạng thái bao gồm các giá trị có thể thay đổi, như giá trị hiện tại của Slider hoặc liệu Checkbox có được chọn hay không. Khi trạng thái của widget thay đổi, đối tượng trạng thái gọi setState() , báo cho framework vẽ lại widget.

Tạo một widget trạng thái

Vấn đề ở đây là gì?

Một widget trạng thái được triển khai bởi hai lớp: một lớp con của StatefulWidget và một lớp con của State .
Lớp trạng thái chứa trạng thái có thể thay đổi của widget và phương thức build() của widget.
Khi trạng thái của widget thay đổi, đối tượng trạng thái gọi setState() , báo cho framework vẽ lại widget.

Trong phần này, bạn sẽ tạo một widget trạng thái tùy chỉnh. Bạn sẽ thay thế hai widget không trạng thái, icon ngôi sao màu đỏ và số đếm bên cạnh nó bằng một widget trạng thái tùy chỉnh duy nhất quản lý một Row với hai widget con: IconButton và Text .

Việc triển khai một widget trạng thái tùy chỉnh yêu cầu tạo hai lớp:

  • Một lớp con của StatefulWidget xác định widget.
  • Một lớp con của State chứa trạng thái cho widget đó và xác định phương thức build() của widget.
    Phần này cho bạn thấy cách xây dựng một widget trạng thái, được gọi là FavoriteWidget , cho ứng dụng Lake. Sau khi thiết lập, bước đầu tiên của bạn là chọn cách quản lý trạng thái cho FavoriteWidget .

Bước 1: Quyết định đối tượng nào quản lý trạng thái của widget

Trạng thái của một widget có thể được quản lý theo nhiều cách, nhưng trong ví dụ của chúng ta, là chính widget đó, FavoriteWidget , sẽ quản lý trạng thái của chính nó. Trong ví dụ này, chuyển đổi ngôi sao là một hành động biệt lập không ảnh hưởng đến widget cha hoặc phần còn lại của giao diện người dùng, vì vậy widget có thể xử lý trạng thái bên trong.

Bước 2: Subclass StatefulWidget

Lớp FavoriteWidget quản lý trạng thái của chính nó, vì vậy nó override createState() để tạo một đối tượng State . Framework gọi createState() khi nó muốn xây dựng widget. Trong ví dụ này, createState() trả về một thể hiện của _FavoriteWidgetState , mà bạn sẽ triển khai trong bước tiếp theo.

class FavoriteWidget extends StatefulWidget {
  @override
  _FavoriteWidgetState createState() => _FavoriteWidgetState();
}

Lưu ý: Member hoặc lớp bắt đầu bằng dấu gạch dưới ( _ ) là private. Để biết thêm thông tin, hãy xem Thư viện và khả năng hiển thị.

Bước 3: Subclass State

Lớp _FavoriteWidgetState lưu trữ dữ liệu có thể thay đổi trong suốt vòng đời của widget. Khi ứng dụng hiển thị lần đầu, giao diện người dùng sẽ hiển thị một ngôi sao màu đỏ đặc, cho biết rằng hồ có trạng thái yêu thích trực tuyến, cùng với 41 lượt thích. Các giá trị này được lưu trữ trong các trường _isFavorited_favoriteCount :

class _FavoriteWidgetState extends State<FavoriteWidget> {
  bool _isFavorited = true;
  int _favoriteCount = 41;
  // ···
}

Lớp này cũng định nghĩa một phương thức build() , tạo ra một Row chứa IconButtonText màu đỏ. Bạn sử dụng IconButton (thay vì Icon) vì nó có thuộc tính onPressed xác định callback (_toggleFavorite ) để xử lý tap. Bạn sẽ xác định callback tiếp theo.

class _FavoriteWidgetState extends State<FavoriteWidget> {
  // ···
  @override
  Widget build(BuildContext context) {
    return Row(
      mainAxisSize: MainAxisSize.min,
      children: [
        Container(
          padding: EdgeInsets.all(0),
          child: IconButton(
            icon: (_isFavorited ? Icon(Icons.star) : Icon(Icons.star_border)),
            color: Colors.red[500],
            onPressed: _toggleFavorite,
          ),
        ),
        SizedBox(
          width: 18,
          child: Container(
            child: Text('$_favoriteCount'),
          ),
        ),
      ],
    );
  }
}

Mẹo: Việc đặt Text trong SizedBox và đặt độ rộng của nó sẽ ngăn chặn một bước nhảy, khi nội dung text thay đổi giữa các giá trị 40 và 41 – một bước nhảy sẽ xảy ra vì các giá trị đó có độ rộng khác nhau.

Phương thức _toggleFavorite() , được gọi khi nhấn IconButton , gọi setState() . Việc gọi setState() là rất quan trọng, bởi vì điều này cho framework biết rằng trạng thái của widget đã thay đổi và widget sẽ được vẽ lại. Đối số hàm để setState() bật tắt giao diện người dùng giữa hai trạng thái này:

void _toggleFavorite() {
  setState(() {
    if (_isFavorited) {
      _favoriteCount -= 1;
      _isFavorited = false;
    } else {
      _favoriteCount += 1;
      _isFavorited = true;
    }
  });
}

Bước 4: Cắm widget trạng thái vào cây widget

Thêm widget trạng thái tùy chỉnh của bạn vào cây widget trong phương thức build() của ứng dụng. Đầu tiên, xác định vị trí mã tạo Icon và Text và xóa nó. Trong cùng một vị trí, tạo tiện ích trạng thái:

layout / lake / {step6 → tương tác} /lib/main.dart
@@ -10,2 +5,2 @@
10 5	   class MyApp extends StatelessWidget {
11 6	   @override
@@ -38,11 +33,7 @@
38 33	   ],
39 34	   ),
40 35	   ),
41	 -  Icon(
36	 +  FavoriteWidget(),
42	 -    Icons.star,
43	 -    color: Colors.red[500],
44	 -  ),
45	 -  Text('41'),
46 37	   ],
47 38	   ),
48 39	   );
@@ -117,3 +108,3 @@
117 108	   );
118 109	   }
119 110	   }

Vậy là xong! Khi bạn hot reload lại ứng dụng, biểu tượng ngôi sao sẽ phản hồi với các tap.

Nguồn (https://flutter.dev/docs/development/ui/interactive#stateful-and-stateless-widgets)

Bài viết liên quan

[Flutter]: Cài đặt Flavors trong Flutter phần 2 – Dành cho iOS

Lời tựa Mặc dù hiện nay đã có nhiều flutter package hỗ trợ việc chia...

[Flutter]: Cài đặt Flavors trong Flutter phần 1 – Dành cho Android

Lời tựa: Mặc dù hiện nay đã có nhiều flutter package hỗ trợ việc chia...

[Flutter] – Giới thiệu Dart Extension Methods

Nguồn Từ bản phát hành Dart 2.6, các nhà phát triển Flutter đã ra mắt...

[Flutter] – Dependency Injection trong Flutter

Soure Trong hướng dẫn này, Quokka sẽ giới thiệu về ba hình thức Dependency Injection...

Tìm hiểu về ngôn ngữ Dart – Phần IX

Hỗ trợ bất đồng bộ Một trong những công việc thường gặp nhất trong phát...

Tìm hiểu về ngôn ngữ Dart – Phần VIII

Generics Nếu bạn xem tài liệu API cho kiểu mảng cơ bản – List, bạn...

Trả lời