Flutter生命周期监听插件did_change_dependencies的使用

Flutter生命周期监听插件did_change_dependencies的使用

作者:Petrus Nguyễn Thái Học

译者:(无需翻译)

did_change_dependencies 插件提供了一个 Stream,当 State.didChangeDependencies 被首次调用时,该 Stream 会发出一个空值并完成事件。

Dart CI

示例

import 'dart:async';

import 'package:did_change_dependencies/did_change_dependencies.dart';
import 'package:flutter/material.dart';
import 'package:rxdart_ext/rxdart_ext.dart';

class Bloc {
  Stream<String> message$ = Stream.empty(); // 仅作演示
}

class MyPage extends StatefulWidget {
  const MyPage({Key? key}) : super(key: key);

  [@override](/user/override)
  _MyPageState createState() => _MyPageState();
}

class _MyPageState extends State<MyPage> with DidChangeDependenciesStream {
  final bloc = Bloc();
  final subscriptions = <StreamSubscription<void>>[];

  [@override](/user/override)
  void initState() {
    super.initState();

    final handle = (String msg) {
      // 安全地访问 ScaffoldMessengerState。
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text(msg)),
      );
    };
    subscriptions << 
        didChangeDependencies$
            .exhaustMap((value) => bloc.message$)
            .listen(handle);

    subscriptions << 
        didChangeDependencies$.listen((event) {
          // 当 `didChangeDependencies` 首次被调用时执行某些操作。
        });
  }

  [@override](/user/override)
  void dispose() {
    super.dispose();
    subscriptions.forEach((s) => s.cancel());
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Container();
  }
}

extension _ListExt<T> on List<T> {
  // 忽略此元素
  void operator <<(T t) => add(t);
}

代码解释

  1. Bloc 类:

    class Bloc {
      Stream<String> message$ = Stream.empty(); // 仅作演示
    }
    

    这里定义了一个简单的 Bloc 类,其中包含一个空的 Stream<String>,用于演示目的。

  2. MyPage 类:

    class MyPage extends StatefulWidget {
      const MyPage({Key? key}) : super(key: key);
    
      [@override](/user/override)
      _MyPageState createState() => _MyPageState();
    }
    

    这是一个简单的 StatefulWidget,其状态由 _MyPageState 管理。

  3. _MyPageState 类:

    class _MyPageState extends State<MyPage> with DidChangeDependenciesStream {
      final bloc = Bloc();
      final subscriptions = <StreamSubscription<void>>[];
    

    _MyPageState 继承自 State<MyPage> 并混入了 DidChangeDependenciesStream。这里定义了 Bloc 实例和订阅列表。

  4. initState 方法:

    [@override](/user/override)
    void initState() {
      super.initState();
    
      final handle = (String msg) {
        // 安全地访问 ScaffoldMessengerState。
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(content: Text(msg)),
        );
      };
      subscriptions << 
          didChangeDependencies$
              .exhaustMap((value) => bloc.message$)
              .listen(handle);
    
      subscriptions << 
          didChangeDependencies$.listen((event) {
            // 当 `didChangeDependencies` 首次被调用时执行某些操作。
          });
    }
    

    initState 中,我们初始化了一些订阅。didChangeDependencies$Stream,当 didChangeDependencies 被首次调用时,它会发出事件。exhaustMap 操作符确保在每次 didChangeDependencies 被调用时,只处理最新的 bloc.message$ 流。另一个订阅用于处理 didChangeDependencies 的事件。

  5. dispose 方法:

    [@override](/user/override)
    void dispose() {
      super.dispose();
      subscriptions.forEach((s) => s.cancel());
    }
    

    dispose 方法中,取消所有订阅以避免内存泄漏。

  6. build 方法:

    [@override](/user/override)
    Widget build(BuildContext context) {
      return Container();
    }
    

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

1 回复

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


在Flutter中,did_change_dependencies 插件允许你监听 Widget 依赖项的变化。这在某些情况下非常有用,比如在依赖注入或需要在依赖项变化时执行特定逻辑时。虽然 Flutter 本身没有直接提供名为 did_change_dependencies 的插件,但你可以通过覆盖 State 类中的 didChangeDependencies 方法来实现类似的功能。

下面是一个示例,展示了如何在 Flutter 中使用 didChangeDependencies 方法来监听依赖项的变化,并假设你想要在依赖项变化时执行一些操作(例如,获取数据或更新 UI)。

首先,确保你的 Flutter 环境已经设置好,并且你有一个正在运行的 Flutter 项目。

示例代码

import 'package:flutter/material.dart';

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

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

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

class _MyHomePageState extends State<MyHomePage> {
  // 假设你有一个依赖项,这里用一个简单的字符串模拟
  String _dependency;

  @override
  void initState() {
    super.initState();
    // 初始化依赖项
    _dependency = "Initial Dependency";
    print("InitState: $_dependency");
  }

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    // 在这里监听依赖项的变化,并执行相应操作
    // 注意:这里的依赖项变化通常是由父 Widget 的重建引起的
    // 这里的代码只是为了演示,实际上你可能需要根据具体情况来判断依赖项是否真的发生了变化
    print("DidChangeDependencies: $_dependency");
    // 假设在某些条件下你需要更新依赖项
    // _updateDependency();
  }

  // 模拟更新依赖项的方法
  void _updateDependency() {
    setState(() {
      _dependency = "Updated Dependency";
      print("Updated Dependency: $_dependency");
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Dependency Listener Demo'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'Current Dependency: $_dependency',
            ),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: () {
                // 模拟触发依赖项变化的操作
                _updateDependency();
                // 注意:这里的按钮点击只是模拟更新依赖项,
                // 在实际场景中,依赖项的变化可能由父 Widget 的重建或其他逻辑触发
              },
              child: Text('Update Dependency'),
            ),
          ],
        ),
      ),
    );
  }

  @override
  void dispose() {
    // 清理资源
    super.dispose();
  }
}

解释

  1. initState 方法:在 Widget 首次构建时调用,用于初始化状态。
  2. didChangeDependencies 方法:在依赖项发生变化时被调用。在这个例子中,每次点击按钮更新依赖项时,这个方法都会被调用,尽管实际上 didChangeDependencies 更常用于响应父 Widget 的依赖项变化。
  3. _updateDependency 方法:模拟更新依赖项的方法,使用 setState 来触发 UI 的重新构建。
  4. 按钮点击事件:点击按钮时调用 _updateDependency 方法,模拟依赖项的变化。

请注意,didChangeDependencies 通常用于响应由父 Widget 引起的依赖项变化,而不是由用户交互(如按钮点击)直接触发。在真实场景中,你可能需要根据具体情况来判断依赖项是否真的发生了变化,并据此执行相应的逻辑。

回到顶部