Có một con bug rất cụ thể dạy cho tất cả mọi người về key. Bạn có một danh sách các dòng có trạng thái — mỗi dòng một checkbox, hoặc một expansion tile, hoặc một ô nhập liệu. Bạn xóa dòng thứ hai. Dòng đó biến mất đúng như mong đợi, nhưng dấu tích vốn thuộc về nó giờ lại nằm trên một dòng khác. Dữ liệu chẳng có gì sai. Tải lại trang thì mọi thứ bình thường. Đó không phải lỗi của Flutter. Đó là framework làm đúng những gì được bảo, và cách sửa chỉ dài một từ. Nhưng cách sửa chỉ thật sự dính lại nếu bạn hiểu quy tắc bên dưới, vì cùng quy tắc đó giải thích vì sao đôi khi key chẳng làm gì cả, vì sao GlobalKey đắt, và vì sao PageStorageKey không thật sự là key theo cùng nghĩa. Ba cây, và cái cây giữ state của bạn Flutter duy trì ba cấu trúc song song. Cây widget là kết quả build của bạn: các đối tượng cấu hình bất biến, bị vứt đi và tạo lại liên tục. Cây render lo layout và vẽ. Nằm giữa hai cái đó là cây element , và đây mới là cái quan trọng ở bài này, vì một Element sống lâu và ...
Phiên bản trong bài hướng dẫn của việc mua hàng trong ứng dụng là một cái nút, một lời gọi buyNonConsumable , và một callback thành công đặt isPremium = true . Phát hành thứ đó rồi bạn sẽ lần lượt phát hiện: người dùng cài lại thì mất sạch, một giao dịch bị cuộc gọi cắt ngang thì không bao giờ hoàn tất, người đã hoàn tiền vẫn giữ quyền truy cập mãi mãi, và bất kỳ ai có bản build đã sửa đều mở khoá ứng dụng miễn phí. Không cái nào trong số đó là trường hợp biên. Chúng là điều kiện vận hành bình thường của một hệ thống thanh toán. Stream mới là API in_app_purchase không hoạt động theo kiểu hỏi-đáp. Giao dịch đến trên một stream, bao gồm cả giao dịch bạn không khởi tạo trong phiên này — các lần khôi phục, giao dịch hoàn tất khi ứng dụng đã đóng, và giao dịch từ thiết bị khác cùng tài khoản. final class PurchaseService { PurchaseService ( this ._iap, this ._backend); final InAppPurchase _iap; final BackendApi _backend; StreamSubscription < List < Purchase...