Flutter GetX依赖注入和绑定
2022-08-02 本文已影响0人
woniu
一、依赖注入
我们前面经常使用Get.put(MyController())
来进行控制器实例的创建,这样就算不使用控制器也会被创建,Getx还有好几种创建实例的方法,如下:
- Get.put():不使用也会被创建控制器实例
- Get.lazyPut():懒加载的方式创建实例,只有在使用的时候才会创建。
- Get.putAsync():
Get.put()
的异步版版本 - Get.create():每次使用都会创建一个新的实例
1、应用程序入口配置
import 'package:flutter/material.dart';
import 'package:flutter_getx_example/DependecyInjectionExample/DependecyInjectionExample.dart';
import 'package:get/get.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return GetMaterialApp(
title: "GetX",
home: DependecyInjectionExample(),
);
}
}
2、创建控制器
import 'package:flutter_getx_example/ObxCustomClassExample/Teacher.dart';
import 'package:get/get.dart';
class MyController extends GetxController {
var teacher = Teacher();
void convertToUpperCase() {
teacher.name.value = teacher.name.value.toUpperCase();
}
}
3、实例化控制器并使用
import 'package:flutter/material.dart';
import 'package:flutter_getx_example/GetXControllerExample/MyController.dart';
import 'package:get/get.dart';
class DependecyInjectionExample extends StatelessWidget {
@override
Widget build(BuildContext context) {
//1、 即使不使用控制器实例也会被创建
// tag将用于查找具有标签名称的实例
// 控制器在不使用时被处理,但如果永久为真,则实例将在整个应用程序中保持活动状态
MyController myController = Get.put(MyController(), permanent: true);
// MyController myController = Get.put(MyController(), tag: "instancel", permanent: true);
// 2、实例将在使用时创建
// 它类似于'permanent',区别在于实例在不被使用时被丢弃
// 但是当它再次需要使用时,get 将重新创建实例
// Get.lazyPut(()=> MyController());
// Get.lazyPut(()=> MyController(), tag: "instancel");
// 3、Get.put 异步版本
// Get.putAsync<MyController>(() async => await MyController());
// 4、每次都将返回一个新的实例
// Get.create<MyController>(() => MyController());
return Scaffold(
appBar: AppBar(
title: Text("GetXController"),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () {
// 实例使用的tag创建
// Get.find<MyController>(tag: 'instancel');获取依赖项
Get.find<MyController>();//获取依赖项
},
child: Text("别点我"))
],
),
),
);
}
}
4、使用实例化的依赖项
4.1 获取依赖项
final controller = Get.find<Controller>();
// OR
Controller controller = Get.find();
4.2 调用依赖项中的方法
controller.increment()
4.3 删除依赖项(通常不需要做,Getx自动管理)
Get.delete<Controller>();
二、Get Service
这个类就像一个 GetxController,它共享相同的生命周期onInit()、onReady()、onClose(),但里面没有逻辑,他只是通知GetX的依赖注入系统,这个子类不同从内存中删除。所以,如果你需要在你的应用程序的生命周期内对一个类实例进行绝对的持久化,就可以使用GetxService。类似于单利。
1、创建Service
import 'package:get/get.dart';
import 'package:shared_preferences/shared_preferences.dart'; //本地存储插件
class Service extends GetxService {
Future <void> getCounter() async{
SharedPreferences prefs = await SharedPreferences.getInstance();
int count = (prefs.getInt("counter") ?? 0) + 1;
print("count 的值为: $count");
await prefs.setInt("counter", count);
}
}
2、初始化Service
import 'package:flutter/material.dart';
import 'package:flutter_getx_example/GetXServiceExample/GetXServiceExample.dart';
import 'package:flutter_getx_example/GetXServiceExample/Service.dart';
import 'package:get/get.dart';
/// 初始化服务
Future<void> main() async {
await initServices(); //第一步,初始化Service
runApp(MyApp());
}
//第二步初始化
Future<void> initServices() async {
print("初始化服务");
await Get.putAsync(() async => await Service());
print("所有服务启动");
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return GetMaterialApp(
title: "GetX",
home: GetXServiceExample(),
);
}
}
3、调用Service
import 'package:flutter/material.dart';
import 'package:flutter_getx_example/GetXServiceExample/Service.dart';
import 'package:get/get.dart';
class GetXServiceExample extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("GetX Service"),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () {
Get.find<Service>().getCounter(); //方法调用
},
child: Text("点我加1"))
],
),
),
);
}
}
三、绑定Binding
在我们使用Getx状态管理器的时候,每次都要手动实例化一个控制器,这样的话基本页面都需要实例化一次,太麻烦,而Binding就可以解决这个问题,可以在项目初始化时把所有需要进行状态管理的控制器进行统一初始化。
1、声明需要绑定的控制器
import 'package:flutter_getx_example/GetXBindingExample/controller/BindingHomeController.dart';
import 'package:flutter_getx_example/GetXBindingExample/controller/BindingMyController.dart';
import 'package:get/get.dart';
class AllControllerBinding implements Bindings {
@override
void dependencies() {
// TODO: implement dependencies
Get.lazyPut<BindingMyController>(() => BindingMyController());
Get.lazyPut<BindingHomeController>(() => BindingHomeController());
}
}
import 'package:get/get.dart';
class BindingHomeController extends GetxController {
var count = 0.obs;
void increment() {
count++;
}
}
import 'package:get/get.dart';
class BindingMyController extends GetxController {
var count = 0.obs;
void increment() {
count++;
}
}
2、在项目启动时进行初始化绑定
import 'package:flutter/material.dart';
import 'package:flutter_getx_example/GetXBindingExample/binding/AllControllerBinding.dart';
import 'package:flutter_getx_example/GetXBindingExample/GetXBindingExample.dart';
import 'package:get/get.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
/// GetX Binding
return GetMaterialApp(
title: "GetX",
initialBinding: AllControllerBinding(), //绑定所有的Controller
home: GetXBindingExample(),
);
}
}
3、在页面中使用状态管理器
import 'package:flutter/material.dart';
import 'package:flutter_getx_example/GetXBindingExample/BHome.dart';
import 'package:flutter_getx_example/GetXBindingExample/binding/BHomeControllerBinding.dart';
import 'package:flutter_getx_example/GetXBindingExample/controller/BindingMyController.dart';
import 'package:get/get.dart';
class GetXBindingExample extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("GetXBinding"),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Obx(() => Text(
"计数器的值为 ${Get.find<BindingMyController>().count}",
style: TextStyle(color: Colors.red, fontSize: 30),
)),
SizedBox(height: 20,),
ElevatedButton(
onPressed: () {
Get.find<BindingMyController>().increment(); //绑定调用
},
child: Text("点击加1")
),
SizedBox(height: 20,),
ElevatedButton(
onPressed: () {
Get.to(BHome());
// Get.toNamed("/bHome");
// Get.to(BHome(), binding: BHomeControllerBinding());
},
child: Text("跳转去首页")
),
],
),
),
);
}
}
在项目中的使用:
- getx_bind:项目入口文件,在此页面绑定页面和依赖项
- HomeBinding:绑定类,在此类添加依赖项(如HomeController)
- HomeView:显示页面,只负责页面内容展示
- HomeController:负责页面逻辑处理
1、get_bind 项目入口文件,在此页面绑定页面和依赖项
void main()=>runApp(GetMaterialApp(
getPages: [
GetPage(name: '/', page: ()=>HomeView(),binding: HomeBinding()),
],
));
2、HomeBinding:绑定类,在此类添加依赖项(如HomeController),使用dependencies方法
class HomeBinding implements Bindings{
@override
void dependencies() {
Get.lazyPut(() => HomeController());
}
}
3、HomeView:显示页面,只负责页面内容展示
class HomeView extends StatelessWidget{
final c = Get.find<HomeController>();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text("Flutter Binding demo")),
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text('You have pushed the button this many times:',),
Obx(()=>Text('${c.count}', style: Theme.of(context).textTheme.headline4,)),
],
),
floatingActionButton: FloatingActionButton(child: Icon(Icons.add), onPressed: c.increment));
}
}
4、HomeController:负责页面逻辑处理
class HomeController extends GetxController{
var count = 0.obs;
increment() => count++;
}