我想我不能理解Fflight中的多提供者,它是如何工作的.

我想分享两个版本的MyTabs类,你可以在下面看到它们. 第二个版本的问题是,只有当 Select 第三个选项卡时才会监听流,但在第一个版本的MyTabs类中我不需要这样做,它会自动监听流,而不 Select 第三个选项卡.

import 'dart:async';

class StreamData {
  final StreamController<int> _valueStreamController = StreamController<int>();
  late Stream<int> valueStream;

  int _counter = 0;

  Stream<int> get myStream => _valueStreamController.stream;

  int get streamCount => _counter;

  StreamData() {
    valueStream = _valueStreamController.stream;
    _startTimer();
  }

  void _startTimer() {
    Timer.periodic(Duration(seconds: 1), (timer) {
      _counter++;
      _valueStreamController.add(_counter);
    });
  }

  void dispose() {
    _valueStreamController.close();
  }
}

第一个版本

class MyTabs extends StatelessWidget {
  MyTabs({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    final Stream<int> myStream = StreamData().myStream;

    return DefaultTabController(
      length: 3,
      child: MultiProvider(
        providers: [
          StreamProvider<int>(
            create: (context) => myStream,
            initialData: 0,
          ),
        ],
        child: Scaffold(
          appBar: AppBar(
            title: const Text('Tab Demo'),
            bottom: const TabBar(
              tabs: <Widget>[
                Tab(text: 'First'),
                Tab(text: 'Second'),
                Tab(text: 'Third'),
              ],
            ),
          ),
          body: const TabBarView(
            children: <Widget>[
              FirstScreen(),
              SecondScreen(),
              ThirdScreen(),
            ],
          ),
        ),
      ),
    );
  }
}

第二版

class MyTabs extends StatelessWidget {
  MyTabs({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return DefaultTabController(
      length: 3,
      child: MultiProvider(
        providers: [
          StreamProvider<int>(
            create: (context) => StreamData().myStream,
            initialData: 0,
          ),
        ],
        child: Scaffold(
          appBar: AppBar(
            title: const Text('Tab Demo'),
            bottom: const TabBar(
              tabs: <Widget>[
                Tab(text: 'First'),
                Tab(text: 'Second'),
                Tab(text: 'Third'),
              ],
            ),
          ),
          body: const TabBarView(
            children: <Widget>[
              FirstScreen(),
              SecondScreen(),
              ThirdScreen(),
            ],
          ),
        ),
      ),
    );
  }
}

我搞不懂多Provider 和数据流是如何工作的.

推荐答案

在这两个版本的代码中,只要调用Create函数,StreamProvider实际上就订阅了流.这并不直接取决于哪个选项卡处于活动状态.订阅行为与构建与每个选项卡关联的小部件树的时间更相关.

您可能会在两个版本之间观察到不同的行为,这可能与时间有关.如果您注意到流仅在"Third"选项卡处于活动状态时才开始发送值,这可能是由于以下原因:

在第二个版本中,流在StreamProvider的Create函数中实例化.这意味着一旦有活动订阅,流就会开始发送值.如果与"第三个"选项卡相关联的小部件是在小部件生命周期的较晚阶段构建的(例如,当第一次 Select 该选项卡时),则似乎只有在"第三个"选项卡处于活动状态时才会发出流.

根据标签的窗口小部件树的 struct 和构建时间的不同,何时建立对流的订阅可能会有所不同,这会给人一种只有在特定选项卡处于活动状态时才开始发出流的印象.

Flutter相关问答推荐

如何更改默认应用程序启动器/启动屏幕

如何更新文本字段的基础上的选定下拉菜单?

在Flutter中,有没有一种方法可以点击页面到后面的页面?

在fltter_widget_from_html中启动url

CLI数据库连接后将SHA-1密钥添加到Firebase项目

遇到图像路径格式问题

如何实现Flutter 梳理机图像的小量移动

'Flutter的无效常数值错误

我想创建一个可滚动的堆叠列表项,每个项都朝向屏幕

没有为类型 'Widget' 定义运算符 '[]' .try 定义运算符[]

如何获取flutter中gridview项目占用的高度和宽度?

在允许屏幕 Select 和点击的同时保持通用对话框显示

Flutter开发中,如何通过'nfc_manager'插件在Android设备上避免默认的New Tag Scanned弹出窗口?

切换 Firebase 项目后 Flutter FirebaseAuthException 'configuration-not-found'

当我将主题更改为深色然后返回浅色模式时,Getx 会Flutter 更改主题,它不会加载我的自定义主题

Flutter Websockets MacOS:相同的代码在调试模式下有效,但在发布模式下无效:(操作系统错误:提供了 node 名或服务名..)

Firebase 中的查询限制 - .orderBy() 错误

我正在try 使用 Firebase 在 Flutter 中使用 Google 注销,但它不起作用

Flutter:如何判断嵌套列表是否包含值

TextSpan 避免符号字符串组上的换行符