Flutter库:Get 【依赖、状态、路由】

Pub地址:get       Github地址:get       Github中文文档:get

一、依赖注入

1.Get.put(普通)

• permanent:是否永久,默认 false 当实例不再使用时会进行销毁,true 则会一直保留。

• tag:标签,用于区分同一个类不同实例。

举例:以下为注入状态控制器。

步骤一:

创建UI页面

class MyOnePage extends StatelessWidget {
  const MyOnePage({super.key});
  @override
  Widget build(context) {
    return Scaffold(
           .......
      );
  }
}

 

步骤二:

创建对应UI页面的业务逻辑类,该类继承GetController类,写入该页面所要维持的状态变量和方法

class MyOnePController extends GetxController{
     // 变量 ... 

     // 方法 ... 
}

 

步骤三:

用Get.put()注入该页面所对应的Controller类的实例化对象,让它可以在所有子路由都可用。其他页面可以通过Get.find()找到该对象,并使用它,如果该对象没有被销毁的话。

class MyOnePage extends StatelessWidget {
  const MyOnePage({super.key});
  @override
  Widget build(context) {

    final MyOnePageController c = Get.put(MyOnePageController ());

    return Scaffold(
           .......
      );
  }
}

 

2.Get.lazyPut(懒加载)

• fenix:类似’永久’,不同的是,当不使用时,实例会被丢弃,但当再次需要使用时,Get会重新创建实例

• tag:标签,用于区分同一个类不同实例。

举例:在状态管理需要find的时候,懒加载注入该页面所对应的Controller类的实例化对象。

步骤一:

同Get.put

步骤二:

同Get.put

步骤三:

final MyOnePageController c = Get.lazyPut(MyOnePageController ());

 

3.Get.putAsync(异步加载)

举例:Get.put()的异步版,以下为异步注入SharedPreferences实例。

Get.putAsync<SharedPreferences>(() async {
    final prefs = await SharedPreferences.getInstance();
    await prefs.setInt('counter', 10);
    return prefs;
});

 

4.Get.create

• permanent:是否永久,默认 false 当实例不再使用时会进行销毁,true 则会一直保留。

• tag:标签,用于区分同一个类不同实例。

表示每次find的时候,都会创建一个新的实例对象。一般不常用。

  Get.create(() => User());

  User user = Get.find();
  User user1 = Get.find();
  print("Get.create 获取的对象比较 ${user == user1}");  // 结果为:false

 

二、状态管理

在Get(x)中,通常分为View层(UI层)、Logic层(业务逻辑+状态)。

1.简单状态

通过GetBuilder和手动update刷新,通常用于刷新ListView,GridView等包含大量List刷新状态的场景。

步骤一:

在Logic层,对业务逻辑需要进行update()刷新。

class CounterLogic extends GetxController {
  var count = 0;

  void increase() {
    ++count;
    update();
  }
}

 

步骤二:

在View层,用Getbuilder嵌套在需要刷新状态的Widget处。

class CounterPage extends StatelessWidget {
  final CounterLogic logic = Get.put(CounterLogic());   // 依赖注入
 
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: GetBuilder<CounterLogic>(builder: (logic) {
          return Text(
            '点击了 ${logic.count} 次'
          );
        }),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () => logic.increase(),
        child: Icon(Icons.add),
      ),
    );
  }
}

2.响应式状态

通过Rx变量Obx(()=>),每一个响应式变量,都会生成对应的GetStream,占用资源大,会对内存造成一定压力,但使用方便一点点。

步骤一:

在Logic层,将变量进行转换为响应式变量。

class CounterLogic extends GetxController {
  var count = 0.obs;   // 在值后面加上obs,即可转换为响应式变量

  void increase() {
    ++count.value;   // 对响应式变量进行计算时,需要加上.value
  }
}

 

步骤二:

在View层,用Obx嵌套在需要刷新状态的Widget处。

class CounterPage extends StatelessWidget {
  final CounterLogic logic = Get.put(CounterLogic());   // 依赖注入
 
  @override
  Widget build(BuildContext context) {
    return Scaffold(
       body: Center(
        child: Obx(() { 
          return Text(
            '点击了 ${logic.count.value} 次'
          );
        }),
       ),
       floatingActionButton: FloatingActionButton(
        onPressed: () => logic.increase(),
        child: Icon(Icons.add),
      ),
    );
  }
}


三、路由管理

在MaterialApp前加上 “Get”,变成GetMaterialApp,从此不再有上下文(context)。

1.普通路由

方法一:进入下一个页面

Get.to(HelloPage(), arguments: {"msg":"hello"});

var map = Get.arguments; //获取参数

• page:进入的下一个页面Widget

• argument:传递参数

 

方法二:返回上一个页面

Get.back();

Get.back(result:'success');  // 返回数据

var data = await Get.to(NextPage());  // 获取返回数据

• result:返回数据参数

 

方法三:进入下一个页面,但没有返回上一个页面的选项(用于闪屏页,登录页面等)

Get.off(NextScreen());

• page:进入的下一个页面Widget

 

方法四:进入下一个页面并取消之前的所有路由(在购物车、投票和测试中很有用)。

Get.offAll(NextScreen());

• page:进入的下一个页面Widget

2.命名路由(常用)

方法一:导航到下一个页面

Get.toNamed("/NextScreen");

Get.toNamed("/NextScreen/:user");  // 带这种参数,用parameters,而不是arguments

Get.parameters['user']

 

方法二:浏览并删除前一个页面

Get.offNamed("/NextScreen");

 

方法三:浏览并删除所有以前的页面

Get.offAllNamed("/NextScreen");

Get.offAllNamed("/NextScreen?device=phone&id=354&name=Enzo");  // 动态网页链接

Get.parameters['id']  // 获取动态网页链接参数,用parameters,而不是arguments

在使用命名路由时,先在GetMaterialApp定义路由。

void main() {
  runApp(
    GetMaterialApp(
      initialRoute: '/',   //初始化路由
      getPages: [    //定义路由数组
        GetPage(name: '/', page: () => MyHomePage()),
        GetPage(name: '/second', page: () => Second()),
      ],
      unknownRoute: GetPage(name: '/notfound', page: () => UnknownRoutePage()),  // 未被定义的路由都会跳转到这里
    )
  );
}

3.Bindings(常用)

Bindings 主要是配合路由进行使用,当通过 GetX 路由进入页面时,会自动调用dependencies方法, 可以在这里进行依赖关系的注册等。

步骤一:依赖注册由原来的View层,放在现在的Binding中。

class CounterBinding implements Bindings {

    @override  void dependencies() {

    Get.lazyPut<CounterController>(() => CounterController());
  }
}

 

步骤二:在路由中,添加对应的Binding。

Get.to(CounterPage(), binding: CounterBinding());  // 普通路由

GetPage( name: '/count', page: () => CounterPage(), binding: CounterBinding() // 在GetMaterialApp-getPages配置)

 

四、组合技(实战技巧)

根据个人经验,在项目中,能简则简。

1.入口函数

关于initialRoute,Home ,routes三个之间的关系

void main() {
  runApp(
    GetMaterialApp(
        getPages: Routes.routePage,  // 代替原生的routes
        title: 'xx',
        initialRoute: '/one',
        initialBinding: BindingsBuilder(
            () => [Get.lazyPut<MyOneController>(() => MyOneController())])),
  );
}

 

2.Routes

单独配置路由类,并在GetPage中直接Binding。

abstract class Routes {

  static const String onePage = '/one';

  static final routePage = [
      GetPage(
          name: onePage,
          page: () => const OnePage(),
          binding: BindingsBuilder(
            () => [Get.lazyPut<OneController>(() => OneController())]))
  ];
}

 

3.GetView

对于单个控制器作为依赖项时,可以继承GetView类,帮我们实现了Get.find(),用的时候,直接使用controller即可。

class OnePage extends GetView<OneController> {
  const OnePage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(title: const Text('MyOnePage')),
        body: Column(
          children: [
            GetBuilder<OneController>(
                builder: (controller) => Text('${controller.obj}')),
            TextButton(
                onPressed: (() => controller.increment()),
                child: const Text('+1'))
          ],
        ));
  }
}

 

五、控件

1.SnackBars

类似于Toast,多用于各种消息提示。

Get.snackbar('Hi', 'i am a modern snackbar'),

2.BottomSheets

从底部弹出的面板。

Get.bottomSheet(
                        Container(
                          child: Wrap(
                            children: <Widget>[
                              ListTile(
                                  leading: Icon(Icons.music_note),
                                  title: Text('Music'),
                                  onTap: () => {}),
                              ListTile(
                                leading: Icon(Icons.videocam),
                                title: Text('Video'),
                                onTap: () => {},
                              ),
                            ],
                          ),
                        ),
                        backgroundColor: Colors.white,
                        shape: const RoundedRectangleBorder(
                            borderRadius: BorderRadius.only(
                                topLeft: Radius.circular(30),
                                topRight: Radius.circular(30))),
                      )

3.Dialogs

Get.defaultDialog(middleText: "这是一个默认弹窗"),

相关资料

1.Flutter之GetX集成及使用详解

2.Flutter状态管理GetX使用详解(带案例)

3.Flutter GetX使用—简洁的魅力!

除非注明,否则均为呆小猴博客原创文章,转载必须以链接形式标明本文链接!付费资源为虚拟物品,一经出售,概不退款!
呆小猴 » Flutter库:Get 【依赖、状态、路由】

发表回复

呆小猴 · 专注安全学习与分享

关于作者 联系作者