美文网首页@IT·互联网
Flutter之Stream、StreamController的

Flutter之Stream、StreamController的

作者: 卢叁 | 来源:发表于2023-10-08 10:41 被阅读0次

    下面的例子展示了如何使用 StreamControllerFlutter 应用中创建一个简单的计数器。其中用到了一个 StreamBuilder 组件来监听 StreamController 的流,并且在新数据发送到流时更新 UI。

    import 'dart:async';
    
    import 'package:flutter/material.dart';
    
    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      const MyApp({super.key});
    
      @override
      Widget build(BuildContext context) {
        return const MaterialApp(
          home: CounterScreen(),
        );
      }
    }
    
    class CounterScreen extends StatefulWidget {
      const CounterScreen({super.key});
    
      @override
      _CounterScreenState createState() => _CounterScreenState();
    }
    
    class _CounterScreenState extends State<CounterScreen> {
      final StreamController<Map<String,dynamic>> _counterController = StreamController<Map<String,dynamic>>();
    
      int _counter = 0;
      Map<String,dynamic> _map = {"test":0};
    
      @override
      void dispose() {
        _counterController.close(); // 关闭 StreamController 以释放资源
        super.dispose();
      }
    
      // 增加计数并将新值发送到流中
      void _incrementCounter() {
        _counter = _counter + 1;
        _counterController.sink.add({"test":_counter});
    
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(title: Text("Counter App")),
          body: Center(
            child: StreamBuilder<Map<String,dynamic>>(
              stream: _counterController.stream,
              initialData: _map, // 初始数据
              builder: (context, snapshot) {
                return Text(
                  'Counter Value: ${snapshot.data?["test"]}',
                  style: TextStyle(fontSize: 20),
                );
              },
            ),
          ),
          floatingActionButton: FloatingActionButton(
            onPressed: _incrementCounter,
            child: const Icon(Icons.add),
          ),
        );
      }
    }
    

    Flutter中,当我们要管理可变状态时,我们通常会使用 StatefulWidget。但是如果我们在 StatelessWidget 中使用外部状态管理(比如 StreamController),我们也能够在没有 StatefulWidget 的情况下响应状态变化。下面的示例中,我们将使用一个 StatelessWidgetStreamController来实现计数器的功能:

    import 'dart:async';
    import 'package:flutter/material.dart';
    
    void main() => runApp(MyApp());
    
    class MyApp extends StatelessWidget {
      final StreamController<Map<String, dynamic>> _counterController = StreamController<Map<String, dynamic>>.broadcast(); // 创建一个广播控制器
      int _counter = 0;
    
      // 增加计数并将新值发送到流中
      void incrementCounter() {
        _counter = _counter + 1;
        _counterController.sink.add({"test": _counter});
      }
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: Scaffold(
            appBar: AppBar(title: Text("Counter App")),
            body: Center(
              child: StreamBuilder<Map<String, dynamic>>(
                stream: _counterController.stream,
                initialData: {"test": 0}, // 初始数据
                builder: (context, snapshot) {
                  return Text(
                    'Counter Value: ${snapshot.data?["test"]}',
                    style: TextStyle(fontSize: 20),
                  );
                },
              ),
            ),
            floatingActionButton: FloatingActionButton(
              onPressed: incrementCounter,
              child: Icon(Icons.add),
            ),
          ),
        );
      }
    }
    

    在上面的代码中,我们创建了一个广播型的 StreamController(.broadcast()),这允许流有多个监听器。incrementCounter方法使计数器增加,并通过流控制器的 sink将新值发送到流中。
    我们使用 StreamBuilder来监听流,并在流中的数据发生变化时重新构建界面。

    注意点

    我们在这里没有使用 dispose 来关闭 StreamController,因为在 StatelessWidget 中没有 dispose 方法。在实际应用中,请确保在适当的地方关闭流,以防止内存泄漏。例如,你可以在页面切换时关闭它,或使用其他状态管理方法(如 GetXRiverpod)来更安全地管理流的生命周期。

    相关文章

      网友评论

        本文标题:Flutter之Stream、StreamController的

        本文链接:https://www.haomeiwen.com/subject/cqcbbdtx.html