Sử dụng chung ChangeNotifier cho nhiều page trong Flutter



Vấn đề ?

Mình có 1 page là profile và login, ở profile mình sử dụng ChangeNotifierProvider để cung cấp một lớp ChangeNotifier (tạm gọi là lớp state) có nhiệm vụ lưu giữ thông tin user hiện tại. Trong trường hợp chưa đăng nhập thì sẽ hiển thị nút đăng nhập yêu cầu chuyển sang page login để người dùng đăng nhập. Sau khi đăng nhập xong sẽ pop quay trở lại page profile. Bây giờ ở màn hình login mình muốn sử dụng được lớp ChangeNotifier của màn hình profile thì phải làm thế nào ?

Một vài cách có thể sử dụng

  1. Khi màn hình login pop sẽ truyền thêm thông tin user trở lại cho màn hình profile, cách này sẽ không hợp lí nếu như dữ liệu update nhiều hơn 1 hoặc ở màn hình login muốn gọi hàm từ lớp state.
  2. Đặt ChangeNotifierProvider ở bên trên materialApp/cupertinoApp: cách này được khá nhiều người sử dụng, thường thì những lớp nào họ muốn dùng chung cho toàn bộ ứng dụng sẽ đặt hết vào 1 MultiProvider và đặt nó ở ngoài cùng (bọc materialApp/cupertinoApp). Nhưng trong trường hợp mình có nhiều page khác nữa mà lại đặt lớp state nằm ở ngoài cùng sẽ dẫn tới tốn bộ nhớ khi không sử dụng tới.
  3. Còn một vài cách khác nữa ví dụ như truyền callback hay jj đó nhưng mình sẽ bỏ qua và chỉ sử dụng những gì sẵn có của provider thôi.

Hướng giải quyết của mình.

Cách của mình là sử dụng ChangeNotifierProvider.value để bọc page mà mình muốn push sang.

Sở dĩ phải bọc thêm 1 ChangeNotifierProvider là vì materialApp/cupertinoApp bản thân nó sử hữu 1 cái Navigator, khi mình push sang màn hình mới lập tức màn hình này sẽ là first child (con đầu tiên) của materialApp/cupertinoApp trong widget tree. Vì nó là con đầu tiên nên 1 là phải đặt ChangeNotifierProvider ở bên trên cả materialApp/cupertinoApp hoặc là phải bọc nó bởi 1 ChangeNotifierProvider mới. Còn 1 cách khác là tạo thêm 1 Navigator khác để tự quản lý cái navigation riêng nhưng rắc rối hơn nên bỏ qua :)) .

Lớp này sẽ cung cấp một ChangeNotifierProvider với một ChangeNotifier sẵn có từ trước, và mình sẽ sử dụng lớp state có sẵn bằng câu lệnh này
Provider.of<classname>(context, listen: false);
Khi từ màn hình profile muốn push sang màn hình login thì sẽ như thế này

Demo 

Đầu tiên tạo Profile page với nội dung như sau Sau đó ở Login page sẽ code như sau

Full source code

2 Nhận xét

Mới hơn Cũ hơn