GETX FLUTTER – STATE MANAGEMENT – CÁCH QUẢN LÝ STATE VỚI OBX
GetX trong Flutter là một thư viện rất tiện ích và được dùng rất nhiều trong lập trình Flutter. GetX cung cấp các giải pháp mạnh mẽ và tiện lợi như : quản lý state có performance cao, dependency injection thông minh, quản lý route nhanh và hiệu quả.
Ở bài viết trước về GetX State management Báo Flutter đã hướng dẫn chi tiết về cách triển khai State Management với GetBuilder. Nhưng trong bài viết này, Báo Flutter tiếp tục hướng dẫn cách triển khai State Management với Obx.
Nắm rõ khái niệm Obx và kiến thức chuyển đổi
Obx : Là một khái niệm viết ghép giữa : Observer và RxDart.
Tức là sử dụng Observer trong RxDart
Từ đó sinh ra các khái niệm : RxString, RxInt, RxDouble, RxBool…
Dưới đây là một ví dụ về chuyển đổi giữa các kiểu dữ liệu static và kiểu dữ liệu Rx.
1 2 |
RxString userNameRx = "Báo Flutter".obs; String userName = userNameRx.value; |
1. Khai báo thư viện
Tạo một project mới và khai báo thư viện mới nhất trong file pubspec.yaml
1 2 3 4 5 6 7 8 9 |
dependencies: flutter: sdk: flutter # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^1.0.2 get: ^4.1.4 |
Tạo cấu trúc project như bên dưới :
2. Sử dụng GetMaterialApp
Khi sử dụng bất cứ tính năng gì của GetX bạn cũng nên khai báo :
1 |
import 'package:get/get.dart'; |
và sử dụng GetMaterialApp trong Widget đầu tiên của ứng dụng.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
import 'package:flutter/material.dart'; import 'package:get/get.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return GetMaterialApp( home: Home(), ); } } |
3. Xác định các giá trị trọng tâm
Trong ví dụ này Báo Flutter muốn truyền các giá trị là thông tin của Báo Flutter từ màn hình Home đến các màn hình khác thông nhờ GetX và khi các giá trị này thay đổi thì các Widget sử dụng những biến này cũng cập nhật theo.
Kịch bản như thế này :
+ Tạo màn hình Home để nhập thông tin của Báo Flutter, Sau đó nhấn nút ” Xác nhận” rồi chuyển sang màn hình khác mà màn hình đó có thể sử dụng được dữ liệu về Báo Flutter thông qua GetX.
Các giá trị cần được truyền đi là các thông tin: tên, số zalo, website, mô tả
Vì thế chúng ta cần tạo một controller :
Tạo một file: information_controller.dart, trong folder : controller
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
import 'package:flutter/material.dart'; import 'package:get/get.dart'; class InformationController extends GetxController{ var name = "".obs; var zalo = "".obs; var website = "".obs; var description = "".obs; updateInformation({@required name, @required zalo, @required website, @required description}){ this.name = name; this.zalo = zalo ; this.website = website; this.description = description; } } |
4.Thực hiện chức năng cập nhật
4.1-Trong folder : resources > widgets , tạo file : common_widgets.dart có nội dung :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
import 'package:flutter/material.dart'; Widget inputWidget({@required label,@required hintText,@required controller}){ return Container( padding: EdgeInsets.all(10), child: TextField( decoration: InputDecoration( border: OutlineInputBorder(), labelText: label, hintText: hintText, ), controller: controller, ), ); } Widget informationWidget({@required label, @required content}) { return Container( padding: EdgeInsets.all(10), child: Row( mainAxisAlignment: MainAxisAlignment.start, children: [ Expanded( flex: 1, child: Text(label)), Expanded( flex: 1, child: Text(content)) ], ), ); } Widget buttonWidget({@required lable,@required colorButton, @required colorText, @required onPress}) { return GestureDetector( child: Container( margin: EdgeInsets.only(top:20), padding: EdgeInsets.only(top: 15, bottom: 15, right: 40, left: 40), decoration: BoxDecoration( color: colorButton, borderRadius: BorderRadius.circular(15), ), child: Text(lable,style: TextStyle(color: colorText, fontSize: 15),), ), onTap: onPress, ); } |
4.2-Tạo file: strings.dart trong : resources > strings
1 2 3 4 5 6 7 8 9 10 |
const String INFORMATION_INPUT = "Nhập thông tin"; const String NAME = "Tên"; const String WEBSITE = "Website"; const String ZALO = "Zalo"; const String DESCRIPTION = "Mô tả"; const String NAME_INPUT = "Nhập tên"; const String ZALO_INPUT = "Nhập số Zalo"; const String WEBSITE_INPUT = "Nhập địa chỉ Website"; const String DESCRIPTION_INPUT = "Nhập mô tả"; const String CONFIRM = "Xác nhận"; |
4.3-Thực hiện tính năng cập nhật thông tin lên “provider”
Tính năng cập nhật thông tin lên “provider” , chúng ta đặt trong button “Xác nhận”.
Chi tiết như đoạn code bên dưới trong home_page.dart:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
import 'package:flutter/material.dart'; import 'package:getx_flutter/controllers/information_controller.dart'; import 'package:getx_flutter/resources/strings.dart'; import 'package:getx_flutter/resources/widgets/common_widgets.dart'; import 'package:get/get.dart'; import 'information_page.dart'; class HomePage extends StatefulWidget { @override _HomePageState createState() => _HomePageState(); } class _HomePageState extends State<HomePage> { TextEditingController nameController, websiteController, zaloController, descriptionController; final inforController = Get.put(InformationController()); @override void initState() { // TODO: implement initState super.initState(); nameController = TextEditingController(); websiteController = TextEditingController(); zaloController = TextEditingController(); descriptionController = TextEditingController(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(INFORMATION_INPUT), centerTitle: true, ), body: SingleChildScrollView( child: Container( padding: EdgeInsets.all(10), child: Column( children: [ // name input inputWidget( label: NAME, hintText: NAME_INPUT, controller: nameController), // Zalo input inputWidget( label: ZALO, hintText: ZALO_INPUT, controller: zaloController), // Website input inputWidget( label: WEBSITE, hintText: WEBSITE_INPUT, controller: websiteController), // description input inputWidget( label: DESCRIPTION, hintText: DESCRIPTION_INPUT, controller: descriptionController), // confirm button buttonWidget( lable: CONFIRM, colorButton: Colors.blue, colorText: Colors.white, onPress: (){ // update information to Provider inforController.updateInformation( name: nameController.text.obs, zalo: zaloController.text.obs, website: websiteController.text.obs, description: descriptionController.text.obs); // Routing to Information Page Get.to(InformationPage()); }) ], ), ), ), ); } } |
Tạo information_page.dart để hiển thị thông tin
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:getx_flutter/controllers/information_controller.dart'; import 'package:getx_flutter/resources/strings.dart'; import 'package:getx_flutter/resources/widgets/common_widgets.dart'; class InformationPage extends StatefulWidget { @override _InformationPageState createState() => _InformationPageState(); } class _InformationPageState extends State<InformationPage> { @override Widget build(BuildContext context) { final InformationController informationController = Get.put(InformationController()); return Scaffold( appBar: AppBar( title: Text(INFORMATION), centerTitle: true, ), body: Container( padding: EdgeInsets.all(10) , child: Column( children: [ informationWidget(label: NAME, content: informationController.name.value), Divider(), informationWidget(label: ZALO, content: informationController.zalo.value), Divider(), informationWidget(label: WEBSITE, content: informationController.website.value), Divider(), informationWidget(label: DESCRIPTION, content: informationController.description.value), Divider(), ], ), ) ); } } |
Hoặc bạn có thể sử dụng Obx để hiển thị lên view:
1 2 3 4 5 6 7 8 9 10 11 12 |
child: Obx(()=>Column( children: [ informationWidget(label: NAME, content: informationController.name.value), Divider(), informationWidget(label: ZALO, content: informationController.zalo.value), Divider(), informationWidget(label: WEBSITE, content: informationController.website.value), Divider(), informationWidget(label: DESCRIPTION, content: informationController.description.value), Divider(), ], )), |
Kết quả
Full SourceCode in Github => GetX Flutter – StateManagement với Obx
Như vậy, Trong việc quản lý State, trong Flutter GetX cũng có phần giống như Provider nhưng viết code với GetX rất gọn gàng và tối giản.
Đặc biệt khi dùng Obs thì độ tối giản và performance sẽ tốt hơn so với dùng GetBuilder thông thường.
Cảm ơn bạn đã theo dõi và tiếp tục đón đọc các chức năng rất hay của GetX trong lập trình Flutter.