Flutter生命周期管理插件lifecycle_provider的使用

Flutter生命周期管理插件lifecycle_provider的使用

在Flutter中,lifecycle_provider 插件能够帮助开发者更好地管理组件的生命周期。以下是该插件的一些优势:

优点

  1. 绑定组件和页面路由的生命周期
  2. 跨页面数据通信,无需公共父控制器
  3. 基于事件的部分更新,调试和更新小部件更加方便
  4. 基于 BaseController 添加 Mixin,便于业务逻辑解耦和重用

监听路由变化

为了监听路由的变化,需要将 LifecycleRouteObserver 添加到 navigatorObservers 中。

[@override](/user/override)
Widget build(BuildContext context) {
  return MaterialApp(
    navigatorObservers: [LifecycleRouteObserver()],
  );
}

状态管理中的生命周期介绍

lifecycle_provider 提供了多种生命周期方法来处理不同阶段的状态变化。

enum LifecycleState {
  /// 对应于 State 的 initState
  /// 只执行一次
  onPageInit,

  /// 在 onPageInit 后立即调用,并且只调用一次
  /// 可以根据上下文获取其他 InheritWidgets 中的数据,并可以获取路由传递的参数
  /// 此方法将调用 State 的 Build 方法,因此不需要在此方法中调用 notifyListeners
  /// 只执行一次
  onPageContextReady,

  /// 当小部件的第一个帧渲染后调用。通常用于初始化网络请求操作
  /// 只执行一次
  onPagePostFrame,

  /// 当页面显示时调用,切换路由或 PageView(如果设置了 pageIndex)时也会调用
  /// 可能会多次执行
  onPageStart,

  /// 当页面显示并且可以响应用户操作时调用,切换路由或 PageView(如果设置了 pageIndex)时也会调用
  /// 当 Dialog 或 BottomSheet 弹出时,下面的页面会调用此方法
  /// 可能会多次执行
  onPageResume,

  /// 页面进入动画结束时调用
  /// 只执行一次
  onPageEnterAnimationEnd,

  /// 当页面无法响应用户操作时调用。当路由切换或 PageView(如果设置了 pageIndex)切换时也会调用
  /// 当 Dialog 或 BottomSheet 显示时,下面的页面会调用此方法
  /// 可能会多次执行
  onPagePause,

  /// 当页面不显示时调用。当路由切换或 PageView(如果设置了 pageIndex)切换时也会调用
  /// 可能会多次执行
  onPageStop,

  /// 当页面退出动画结束时调用,但可能不会回调。例如,当使用 replace 方法切换路由时,此方法不会被调用。
  /// 只执行一次
  onPageLeaveAnimationEnd,

  /// 当页面销毁时调用
  /// 只执行一次
  onPageDispose,

  /// 应用程序进入前台
  onAppResume,

  /// 应用程序处于非活动状态
  onAppInactive,

  /// 应用程序暂停
  onAppPause,

  /// 当应用程序从后台进入前台时调用
  onAppForeground,

  /// 当应用程序从前台进入后台时调用
  onAppBackground;
}

如何更新组件

使用状态管理的控制器可以继承自 BaseController 并使用 NotifyMixin, LifecycleMixin 等 Mixin。

abstract class BaseController<T extends Enum> extends ChangeNotifier
    with NotifyMixin<T>, LifecycleMixin, EventBusMixin {
  [@override](/user/override)
  @mustCallSuper
  void onPageInit() {
    super.onPageInit();
    registerIds(shouldNotifyIds);
  }

  List<T> get shouldNotifyIds;
}

// 示例代码
enum UpdatePageEvent { update }

class UpdatePageController extends BasePageController<UpdatePageEvent> {
  [@override](/user/override) List<UpdatePageEvent> get shouldNotifyIds => UpdatePageEvent.values;
  int _count = 0;

  int get count => _count;

  void increase() {
    _count++;
    notifySingleListener(UpdatePageEvent.update);
  }
}

class UpdatePage extends BasePage<UpdatePageController> {
  const UpdatePage({super.key});

  [@override](/user/override)
  UpdatePageController createController(BuildContext context) {
    return UpdatePageController();
  }

  [@override](/user/override)
  Widget providerStateBuild(BuildContext context, UpdatePageController controller) {
    return Scaffold(
      appBar: AppBar(title: const Text('UpdatePage')),
      body: Center(
        child: SelectorIds<UpdatePageEvent, UpdatePageController>(
          ids: const [UpdatePageEvent.update],
          builder: (_, controller, __) {
            return Text('Current value is: ${controller.count}');
          },
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () => controller.increase(),
        child: const Icon(Icons.add),
      ),
    );
  }
}

实现跨页面通信

通过 EventBusMixin 可以实现跨页面通信。

class PageOneController extends BasePageController {
  /// 发送事件
  void sendLoginEvent() {
    dispatchEvent(const LoginEvent(true));
  }
}

class PageTwoController extends BasePageController {
  [@override](/user/override)
  void onInit() {
    super.onInit();

    /// 监听事件
    observeEvent<LoginEvent>((event) {
      debugPrint('Login event received----${event.isLogin}');
    });
  }
}

完整示例代码

import 'package:example/page_view/bottom_nav_page.dart';
import 'package:example/page_view/tab_page.dart';
import 'package:example/pages/dialog_page.dart';
import 'package:example/pages/drawer_page.dart';
import 'package:example/pages/pop_page.dart';
import 'package:example/pages/pop_until_page.dart';
import 'package:example/pages/replace_page.dart';
import 'package:example/pages/update_page.dart';
import 'package:flutter/material.dart';
import 'package:lifecycle_provider/lifecycle_provider.dart';

import 'home_page.dart';
import 'root_controller.dart';

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  AppLifecycleManager.instance.listen();
  runApp(const MyApp());
}

class MyApp extends BasePage<RootController> {
  const MyApp({super.key});

  [@override](/user/override)
  RootController createController(BuildContext context) {
    return RootController();
  }

  [@override](/user/override)
  Widget providerStateBuild(BuildContext context, RootController controller) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(primarySwatch: Colors.blue, useMaterial3: false),
      routes: {
        "/tabPage": (_) => const TabPage(),
        "/bottomNav": (_) => const BottomNavPage(),
        "/drawer": (_) => const DrawerPage(),
        "/popPage": (_) => const PopPage(),
        "/popUntilPage": (_) => const PopUntilPage(),
        "/replace": (_) => const ReplacePage(),
        "/dialog": (_) => const DialogPage(),
        "/updatePage": (_) => const UpdatePage(),
      },
      home: const HomePage(),
      navigatorObservers: [LifecycleRouteObserver()],
    );
  }
}

更多关于Flutter生命周期管理插件lifecycle_provider的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter生命周期管理插件lifecycle_provider的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个关于如何在Flutter中使用lifecycle_provider插件进行生命周期管理的代码案例。lifecycle_provider是一个可以帮助你在Flutter应用中更好地管理组件生命周期的插件。

1. 添加依赖

首先,你需要在pubspec.yaml文件中添加lifecycle_provider依赖:

dependencies:
  flutter:
    sdk: flutter
  lifecycle_provider: ^0.4.0  # 请注意版本号,根据实际需要调整

然后运行flutter pub get来获取依赖。

2. 使用LifecycleProvider

接下来,你可以在你的Flutter应用中使用LifecycleProvider来监听生命周期事件。以下是一个简单的例子:

主文件 main.dart

import 'package:flutter/material.dart';
import 'package:lifecycle_provider/lifecycle_provider.dart';
import 'page.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: LifecycleProvider(
        child: MyHomePage(),
      ),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Lifecycle Provider Example'),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            Navigator.push(
              context,
              MaterialPageRoute(builder: (context) => SecondPage()),
            );
          },
          child: Text('Go to Second Page'),
        ),
      ),
    );
  }
}

第二页面 page.dart

import 'package:flutter/material.dart';
import 'package:lifecycle_provider/lifecycle_provider.dart';

class SecondPage extends StatefulWidget {
  @override
  _SecondPageState createState() => _SecondPageState();
}

class _SecondPageState extends State<SecondPage> with WidgetsBindingObserver {
  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance!.addObserver(this);
    LifecycleProvider.of(context).addListener(this);
  }

  @override
  void dispose() {
    WidgetsBinding.instance!.removeObserver(this);
    LifecycleProvider.of(context).removeListener(this);
    super.dispose();
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    if (state == AppLifecycleState.resumed) {
      print('App is resumed');
    } else if (state == AppLifecycleState.inactive) {
      print('App is inactive');
    } else if (state == AppLifecycleState.paused) {
      print('App is paused');
    } else if (state == AppLifecycleState.detached) {
      print('App is detached');
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Second Page'),
      ),
      body: Center(
        child: Text('Lifecycle Provider is working!'),
      ),
    );
  }
}

3. 解释

  • LifecycleProvider: 我们在MyApphome属性中使用了LifecycleProvider,它包裹了MyHomePage
  • WidgetsBindingObserver: 在SecondPage中,我们让状态类实现了WidgetsBindingObserver接口,这样可以监听应用的生命周期事件。
  • addListener/removeListener: 在initStatedispose方法中,我们分别添加了和移除了对LifecycleProvider的监听。
  • didChangeAppLifecycleState: 实现了didChangeAppLifecycleState方法,根据应用的生命周期状态进行不同的处理。

通过这种方式,你可以在Flutter应用中更好地管理组件的生命周期,并根据不同的生命周期状态执行相应的操作。

回到顶部