Flutter StreamBuilder的快照在发送后没有日期--snapshot.data总是设置为initialData。

问题描述 投票:0回答:1

在这个(我正在构建的一个应用程序的一小部分)中,我有一排按钮,它使用流来选择一个行为(即显示数据的时间范围),这工作没有问题。然后我想通过设置按钮颜色来改变所选行为,比如说Colors.red。为此,我使用了一个流,对按下的按钮取值,以适当的颜色重建按钮行。

不知道为什么,snapshot.data等于initialData:无论我按了什么按钮。我检查了流值是添加的值,为了使StreamController表现正确,我就把snapshot.data测试替换为var data = stream.listen((x) => data = x)的测试,这样就可以了。

我只是不明白发生了什么

flutter doctor -v[✓] Flutter (Channel stable, v1.17.2, on Mac OS X 10.15.4 19E287, locale en-FR) - Flutter version 1.17.2 at usrlocalflutter - Framework revision 5f21edf8b6 (4 days ago), 2020-05-28 12:44:12 -0700 - Engine revision b851c71829 - Dart version 2.8.3.

[✓] Android工具链--为Android设备开发(Android SDK版本28.0.3)--Android SDK在UsersjfbLibraryAndroidsdk--平台android-29,构建工具28.0.3--Java二进制在。LibraryJavaJavaVirtualMachinesadoptopenjdk-8.jdkContentsHomebinjava - Java版本OpenJDK运行时环境(AdoptOpenJDK)(build 1.8.0_242-b08) - 接受所有Android许可证。

[✓] Xcode - 为iOS和macOS开发(Xcode 11.4.1) - Xcode at ApplicationsXcode.appContentsDeveloper - Xcode 11.4.1,Build版本11E503a - CocoaPods版本1.9.1。

[!] Android Studio (未安装) - 未找到 Android Studio; 下载地址为 https:/developer.android.comstudioindex.html。 (或访问 https:/flutter.devdocsget-startedinstallmacos#android-setup。 详细说明)。)

[✓] 已连接的设备 (1 可用) - iPhone 11 - 17CF5871-B9F8-4739-B8BB-607807AD0530 - ios - com.apple.CoreSimulator.SimRuntime.iOS-13-4 (模拟器)

! 医生发现1类问题。

这一部分的代码 。

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:weight_trend/blocs/bloc_provider.dart';
import 'package:weight_trend/blocs/chart_bloc.dart';

var myStream = StreamController<int>.broadcast();
Stream stream = myStream.stream;
var data;  // normally should use snapshot.data

class ChartRangeSelectionButtons extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return StreamBuilder(
      stream: myStream.stream,
      initialData: 2,
      builder: (context, snapshot) {
        myStream.stream.listen((x) => data = x);
        print(snapshot.data);
        if (data == 1) {
          return Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: <Widget>[
              ChartButton(title: '1W', buttonColor: Colors.red),
              ChartButton(title: '2W'),
              ChartButton(title: '3W'),
              ChartButton(title: '4W'),
            ],
          );
        } else if (data == 2) {
          return Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: <Widget>[
              ChartButton(title: '1W'),
              ChartButton(title: '2W', buttonColor: Colors.red),
              ChartButton(title: '3W'),
              ChartButton(title: '4W'),
            ],
          );
        } else if (data == 3) {
          return Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: <Widget>[
              ChartButton(title: '1W'),
              ChartButton(title: '2W'),
              ChartButton(title: '3W', buttonColor: Colors.red),
              ChartButton(title: '4W'),
            ],
          );
        } else {
          return Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: <Widget>[
              ChartButton(
                title: '1W',
              ),
              ChartButton(
                title: '2W',
              ),
              ChartButton(title: '3W'),
              ChartButton(title: '4W', buttonColor: Colors.red),
            ],
          );
        }
      },
    );
  }
}

class ChartButton extends StatelessWidget {
  const ChartButton({this.title, this.buttonColor = Colors.white});
  final String title;
  final buttonColor;
  @override
  Widget build(BuildContext context) {
    return Container(
      width: 60,
      child: RaisedButton(
        onPressed: () {
          if (title == '1W') {
            BlocProvider.of<ChartBloc>(context).inputEvent.add(ChartRange.one);
            myStream.sink.add(1);
          } else if (title == '2W') {
            BlocProvider.of<ChartBloc>(context).inputEvent.add(ChartRange.two);
            myStream.sink.add(2);
          } else if (title == '3W') {
            BlocProvider.of<ChartBloc>(context)
                .inputEvent
                .add(ChartRange.three);
            myStream.sink.add(3);
          } else if (title == '4W') {
            BlocProvider.of<ChartBloc>(context).inputEvent.add(ChartRange.four);
            myStream.sink.add(4);
          }
        },
        color: buttonColor,
        textColor: Colors.black,
        splashColor: Colors.grey.shade400,
        child: Text(title),
      ),
    );
  }
}
flutter stream
1个回答
0
投票

我已经用你的代码做了一个简单的例子,似乎工作正常。

2
2
3
1

你为什么要用Bloc?对我来说,这种类型的东西似乎是矫枉过正的,就从简单的开始吧。

import 'package:flutter/material.dart';
import "dart:async";

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        body: Center(
          child: ChartRangeSelectionButtons(),
        ),
      ),
    );
  }
}

var myStream = StreamController<int>.broadcast();
Stream stream = myStream.stream;
var data;  // normally should use snapshot.data

class ChartRangeSelectionButtons extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return StreamBuilder(
      stream: myStream.stream,
      initialData: 2,
      builder: (context, snapshot) {
        //myStream.stream.listen((x) => data = x);
        print(snapshot.data);
        if (data == 1) {
          return Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: <Widget>[
              ChartButton(title: '1W', buttonColor: Colors.red),
              ChartButton(title: '2W'),
              ChartButton(title: '3W'),
              ChartButton(title: '4W'),
            ],
          );
        } else if (data == 2) {
          return Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: <Widget>[
              ChartButton(title: '1W'),
              ChartButton(title: '2W', buttonColor: Colors.red),
              ChartButton(title: '3W'),
              ChartButton(title: '4W'),
            ],
          );
        } else if (data == 3) {
          return Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: <Widget>[
              ChartButton(title: '1W'),
              ChartButton(title: '2W'),
              ChartButton(title: '3W', buttonColor: Colors.red),
              ChartButton(title: '4W'),
            ],
          );
        } else {
          return Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: <Widget>[
              ChartButton(
                title: '1W',
              ),
              ChartButton(
                title: '2W',
              ),
              ChartButton(title: '3W'),
              ChartButton(title: '4W', buttonColor: Colors.red),
            ],
          );
        }
      },
    );
  }
}

class ChartButton extends StatelessWidget {
  const ChartButton({this.title, this.buttonColor = Colors.white});
  final String title;
  final buttonColor;
  @override
  Widget build(BuildContext context) {
    return Container(
      width: 60,
      child: RaisedButton(
        onPressed: () {
          if (title == '1W') {
            //BlocProvider.of<ChartBloc>(context).inputEvent.add(ChartRange.one);
            myStream.sink.add(1);
          } else if (title == '2W') {
            //BlocProvider.of<ChartBloc>(context).inputEvent.add(ChartRange.two);
            myStream.sink.add(2);
          } else if (title == '3W') {
            //BlocProvider.of<ChartBloc>(context).inputEvent.add(ChartRange.three);
            myStream.sink.add(3);
          } else if (title == '4W') {
            //BlocProvider.of<ChartBloc>(context).inputEvent.add(ChartRange.four);
            myStream.sink.add(4);
          }
        },
        color: buttonColor,
        textColor: Colors.black,
        splashColor: Colors.grey.shade400,
        child: Text(title),
      ),
    );
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.