, August 13, 2022

0 kết quả được tìm thấy

Tìm hiểu Keys trong Flutter

  • Đăng bởi  Kieu Hoa
  •  Jul 20, 2021

  •   6 min reads
Tìm hiểu Keys trong Flutter

Trong bài viết này, chúng ta sẽ cùng nhau khám phá các Keys trong Flutter. Không những tìm hiểu công dụng của từng loại Key, chúng ta còn biết được khi nào, ở đâu và sử dụng loại nào là thích hợp để giải quyết các vấn đề cũng như nó đã tối ưu ứng dụng của chúng ta như thế nào.

1. Khi nào nên sử dụng Key

Về cơ bản, các bạn có thể dễ dàng nhận thấy được Key được sử dụng trong bất kỳ hàm dựng của mọi Widget. Tuy nhiên, bạn cũng hiếm khi sử dụng Key trong khi thực hiện lồng ghép các Widget lại với nhau để dựng layout (đoán thui :v). Các key duy trì State khi các Widget di chuyển trong Widget tree của ứng dụng Flutter. Dưới đây là một số ví dụ cụ thể:

class NewStatelessWidget extends StatelessWidget {
  const NewStatelessWidget({ Key? key }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      
    );
  }
}
class NewStatefulWidget extends StatefulWidget {
  const NewStatefulWidget({ Key? key }) : super(key: key);

  @override
  _NewStatefulWidgetState createState() => _NewStatefulWidgetState();
}

class _NewStatefulWidgetState extends State<NewStatefulWidget> {
  @override
  Widget build(BuildContext context) {
    return Container(
      
    );
  }
}
ListTile(
  key: UniqueKey(),
  title: Text(
     text,
     style: textStyle ?? Theme.of(context).textTheme.bodyText2,
  ),
)

Dưới đây mình sẽ recap lại một tí về video trên (Lưu ý mình có thay đổi tên các class). Đầu tiên, chúng ta có 1 class StatefulWidget tên là PositionedKey. Ở phiên bản đầu tiên, hàm initState() nhận vào 2 Widget có cùng tên class là StatelessColorful. Đọc tên thôi cũng biết đây là StatelessWidget. Mục đích là hiển thị 2 ô có màu khác nhau trên màn hình trên cùng 1 dòng (nhìn ở dưới hàm build thì nó được bỏ vào 1 cái Row).

import 'package:flutter/material.dart';
import 'dart:math';
class PositionedKey extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => PositionedKeyState();
}
class PositionedKeyState extends State<PositionedKey> {
  List<Widget> tiles;
  
@override
  void initState() {
    super.initState();
    tiles = [
      StatelessColorful(),
      StatelessColorful(),
    ];
  }
@override
  Widget build(BuildContext context) {
    return Scaffold(
        body: SafeArea(
            child: Center(
                child: Row(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: tiles))),
        floatingActionButton: FloatingActionButton(
            child: Icon(Icons.sentiment_very_satisfied), onPressed: swapTiles));
  }
  
  void swapTiles(){
  	setState(() {
      tiles.insert(1,tiles.removeAt(0));
    });
  }

Sau đó, khi ta nhấn vào floatingActionButton, hàm onPressed sẽ gọi đến function swapTiles() để hoán đổi vị trí của 2 ô và dĩ nhiên là nó work như chúng ta mong muốn.

Một điều lưu ý mà team Flutter có nói trong video đó là:

Remember, if the entire widget subtree in your collection is stateless, keys aren't needed.

(Tạm dịch: Key sẽ không cần thiết nếu như các widget subtree là các StatelessWidget).

Bạn có thể tham khảo code khởi tạo class StatelessColorful như sau:

class StatelessColorful extends StatelessWidget {
  final Color color = UniqueColorGenaretor.getColor();
StatelessColorful({Key key}) : super(key: key);
@override
  Widget build(BuildContext context) => buildColorful(color);
}

Vậy trong trường hợp StatefulWidget thì sao? Chúng ta sẽ thay đổi class ở trong hàm initState() thành class StatefulColorful. Sau đó chúng ta nhấn vào floatingActionButton, hàm onPressed sẽ gọi đến function swapTiles() và bạn sẽ thấy một điều kỳ lạ xảy ra, đó là không có gì xảy ra hay thay đổi gì cả :))).

class StatefulColorful extends StatefulWidget {
  StatefulColorful({Key key}) : super(key: key);
@override
  State<StatefulWidget> createState() => StatefulColorfulState();
}
class StatefulColorfulState extends State<StatefulColorful> {
  Color color;
@override
  void initState() {
    super.initState();
    color = UniqueColorGenaretor.getColor();
  }
@override
  Widget build(BuildContext context) => buildColorful(color);
}

Khi ta chuyển sang sử dụng StatefulWidget thì lúc này biến color đã được lưu trữ ở trong State rồi, cho nên dù có nhấn bao nhiêu lần thì vẫn vậy, giống như crush của bạn trong State (lòng, trái tim, v.v) có chứa người khác rồi :v.

Sau khi chuyển sang StatefulWidget

Ok tình hình có vẻ không khả thi với cách cũ, ta nên thay đổi cách tiếp cận mới để đạt được kết quả mới. Mọi vấn đề chỉ cần xác định đâu là KeyPoint để giải quyết, và lần này may mắn ta chỉ cần dùng Key là giải quyết được (nhớ tìm đâu là Key để mở khoá trái tim nàng nha mấy ông :v).

void initState() {
  super.initState();
  tiles = [
    StatefulColorfulTile(key: UniqueKey()),
    StatefulColorfulTile(key: UniqueKey()),
  ];
}

Sau khi thêm, bạn hãy chạy lại code (nhớ Restart App nhé), bạn sẽ thấy chúng đã hoán đổi vị trí với nhau. Vấn đề nằm ở chỗ khi bạn hoán đổi vị trí mà không có Key, Flutter không thể nào phân biệt được sự thay đổi mà update lại đúng reference.

2. Sử dụng Key ở đâu sao cho hợp lý:

Thông thường, nó phải được đặt trong Widget cấp cao (high-level) của cây Widget hiện tại. Trong ví dụ trên, ta bọc thêm Padding cho mỗi StatefulColorful. Sau đó ta nhấn lại thì thấy màu của hai ô đã thay đổi ngẫu nhiên trong khi chúng ta muốn nó phải cố định.

3. Tổng hợp Key trong Flutter

  • Value Key: Ví dụ bạn đang xây dựng ứng dụng ToDo App, mỗi ToDo item thường có một thuộc tính có giá trị là duy nhất hoặc hằng số để bạn phân biệt giữa các item Todo với nhau (thuộc tính đó thường là id). Trong trường hợp này, bạn nên sử dụng ValueKey. Nó sẽ giúp cho việc thêm, xoá, sửa 1 ToDo bất kỳ nhanh hơn, đặc biệt là với xoá.
  • Object Key: Giả sử rằng mỗi Widget con lưu trữ một tổ hợp dữ liệu phức tạp, chẳng hạn như một ứng dụng lưu trữ sổ địa chỉ cho thông tin người dùng. Bất kỳ trường thông tin nào, chẳng hạn như tên hoặc ngày sinh, có thể giống với một người khác, nhưng mỗi một tập dữ liệu là duy nhất. Trong những trường hợp này,ObjectKeylà phù hợp nhất.
  • Unique Key: Nếu có nhiều widget có cùng loại hoặc nếu bạn cần đảm bảo rằng widget con không giống với các widget khác, bạn có thể sử dụng UniqueKey. Chúng ta đã sử dụng nó trong ví dụ của mình.UniqueKeyBởi vì chúng ta không lưu trữ một số thông tin khác về khối màu và chúng tôi không có ý tưởng tuyệt vời về màu sắc cho đến khi chúng ta lắp ráp widget (cho nó random color).
  • GlobalKeys: có hai cách sử dụng:
  1. Chúng cho phép các Widget thay đổi parents của chúng ở bất kỳ vị trí nào trong ứng dụng mà không bị mất state hoặc chúng có thể được sử dụng để truy cập dữ liệu để lấy thông tin của một Widget bất kỳ.
  2. Trong trường hợp thứ hai, bạn có thể cần kiểm tra mật khẩu; tuy nhiên, bạn không muốn chia sẻ status data với các widget khác nhau trong cây và bạn có thể sử dụng GlobalKey<FromState>, nó nắm giữ State của Form.

Sự thật mà nói, GlobalKey giống như một biến toàn cục. Có những cách khác tốt hơn để hoàn thành công việc của các key đó, chẳng hạn như inherited widget, Redux, or block pattern.

Tóm lại:

Trong bài viết, tôi đã giải thích cấu trúc cơ bản của Keys In Flutter, bạn có thể sửa đổi code này theo sự lựa chọn của mình và đây là phần giới thiệu cơ bản về Keys In Flutter từ tôi và cách hoạt động của nó trong Flutter.

Bài viết được dịch và viết lại từ bài gốc: Keys In Flutter

Bài viết liên quan

So sánh StatelessWidget và StatefulWidget

Trong bài viết này, các bạn sẽ có cái nhìn tổng quát về hai loại widget lớn nhất là StatelessWidget và StatefulWidget....

So sánh StatelessWidget và StatefulWidget
Tổng hợp các Shortcuts, Extensions & Settings trong VSCode khi lập trình Flutter

Trong bài viết này, mình sẽ liệt kê cho bạn các shortcuts, extensions, setting mà bạn nên sử dụng để lập trình Flutter hàng ngày....

Tổng hợp các Shortcuts, Extensions & Settings trong VSCode khi lập trình Flutter
[Phần 1] Những extension cần thiết khi làm việc với Flutter trên VS Code

VS Code là 1 text editor tuyệt vời được phát triển bởi Mircosoft. Đây là một trong các công cụ được developer trên toàn thế giới yêu thích vì sự tiện lợi, dễ dùng và nó chứa hàng ngàn, thậm chí trăm ngàn các extension phục vụ cho bạn trong quá trình bạn phát triển phần mềm....

[Phần 1] Những extension cần thiết khi làm việc với Flutter trên VS Code
Fix lỗi Flutter 3 không thể build app trên iOS

Cách fix lỗi Flutter 3 không thể build và run được app trên iOS với video hướng dẫn chia tiết...

Fix lỗi Flutter 3 không thể build app trên iOS
Flutter Coding UI Speed Code

Nhận bản UI siêu đẹp nhưng làm sao để phân tích rồi code ra một cách chính xác nhất? Series này 200Lab sẽ cho bạn một góc nhìn thực tế về quá trình code UI cho app Movie Ticket....

Flutter Coding UI Speed Code
You've successfully subscribed to 200Lab Blog
Great! Next, complete checkout for full access to 200Lab Blog
Xin chào mừng bạn đã quay trở lại
OK! Tài khoản của bạn đã kích hoạt thành công.
Success! Your billing info is updated.
Billing info update failed.
Your link has expired.