【问题标题】:How implement StreamBuilder correctly flutter如何正确实现 StreamBuilder
【发布时间】:2021-08-17 09:11:54
【问题描述】:

我是 flutter 的新手。我正在研究使用 Futurebuilder 从服务器获取数据的项目,但我现在想通过 StreamBuilder 更改它。在这种情况下我应该修改什么。如何正确移动到 StreamBuilder?

这是我的代码:

Widget build(BuildContext context) {
    Size size = MediaQuery.of(context).size;
    return SafeArea(     
        child: Center(
      child: Scaffold(     
          body: SingleChildScrollView(
              child: Form(
                  key: _formKey,
                  child: FutureBuilder(
                      future: future,
                      builder: (context, snapshot) {
                        switch (snapshot.connectionState) {
                          case ConnectionState.none:
                            return Text('no connection');
                          case ConnectionState.active:
                          case ConnectionState.waiting:
                            return Center(
                              child: CircularProgressIndicator(),
                            );
                            break;
                          case ConnectionState.done:
                            if (snapshot.hasError) {
                              return Text('error');
                            } else if (snapshot.hasData) {
                              return Column(
                                mainAxisAlignment:
                                    MainAxisAlignment.spaceEvenly,
                                children: [
                                  Container(
                                    padding: EdgeInsets.only(top: 16),
                                    width: MediaQuery.of(context).size.width,
                                    height:
                                        MediaQuery.of(context).size.height / 4,
                                    decoration: BoxDecoration(
                                        boxShadow: [
                                          BoxShadow(
                                              color: Colors.white60,
                                              blurRadius: 15.0,
                                              offset: Offset(0.0, 0.75))
                                        ],
                                        gradient: LinearGradient(
                                          begin: Alignment(0.5, 0.85),
                                          end: Alignment(0.48, -1.08),
                                          colors: [
                                            const Color(0xFF0B0C3A),
                                            const Color(0xFF010611),
                                          ],
                                          stops: [
                                            0.0,
                                            0.5,
                                          ],
                                        ),
                                        borderRadius: BorderRadius.only(
                                            bottomRight: Radius.circular(32),
                                            bottomLeft: Radius.circular(32))),
                                    child: Column(
                                      children: [
                                        Row(
                                          children: [
                                            SizedBox(
                                              width: 30,
                                            ),
                                            Column(
                                                crossAxisAlignment:
                                                    CrossAxisAlignment.start,
                                                children: [
                                                  Text(
                                                    "$name",
                                                    style: TextStyle(
                                                        color: Colors.white,
                                                        fontSize: 25,
                                                        fontWeight:
                                                            FontWeight.bold),
                                                  ),
                                                  SizedBox(
                                                    height: 10,
                                                  ),
                                                  Text(
                                                    "$phone",
                                                    style: TextStyle(
                                                      color: Colors.white60,
                                                      fontSize: 18,
                                        
                                        ),
                                        Row(
                                          mainAxisAlignment:
                                              MainAxisAlignment.end,
                                          children: [
                                            Container(
                                                margin: EdgeInsets.symmetric(
                                                    vertical: 10),
                                                width: size.width * 0.4,
                                                child: ElevatedButton(
                                                  onPressed: () {
                                                    if (_nameController.text ==
                                                            "" &&
                                                        _emailController.text ==
                                                            "" &&
                                                        _adressController
                                                                .text ==
                                                            "") {
                                                      setState(() =>
                                                          isButtonDisabled =
                                                              true);
                                                    } else {
                                                      editUserProfile();
                                                    }
                                                  },    
                                                  child: Text('Enregistrer'),
                                                  style:
                                                      ElevatedButton.styleFrom(
                                                    primary: Colors.transparent,
                                                    shape:
                                                        RoundedRectangleBorder(
                                                            borderRadius:
                                                                BorderRadius
                                                                    .circular(
                                                                        20),
                                                            side: BorderSide(
                                                                color: Colors
                                                                    .white)),
                                                  ),
                                                )),
                                            SizedBox(
                                              width: 20,
                                  Container(
                                    height: MediaQuery.of(context).size.height /
                                        1.5,
                                    child: Column(
                                      mainAxisAlignment:
                                          MainAxisAlignment.start,
                                      children: [
                                        Column(
                                          mainAxisAlignment:
                                              MainAxisAlignment.start,
                                          children: [
                                            Container(
                                              width: size.width * 0.94,
                                              child: Column(
                                                mainAxisAlignment:
                                                    MainAxisAlignment.start,
                                                children: [
                                                  Container(
                                                    padding: EdgeInsets.only(
                                                        left: 10,
                                                        right: 10,
                                                        bottom: 20,
                                                        top: 20),
                                                    child: Column(
                                                      mainAxisAlignment:
                                                          MainAxisAlignment
                                                              .start,
                                                      crossAxisAlignment:
                                                          CrossAxisAlignment
                                                              .start,
                                                      children: [
                                                        Row(
                                                          mainAxisAlignment:
                                                              MainAxisAlignment
                                                                  .spaceBetween,
                                                          children: [
                                                            Text(
                                                              'Votre nom :',
                                                              style: TextStyle(
                                                                  color: Color(
                                                                      0xFF4053FCF),
                                                                  fontSize: 16,
                                                                  fontWeight:
                                                                      FontWeight
                                                                          .w600),
                                                            ),
                                                            IconButton(
                                                                icon: Icon(
                                                                  CommunityMaterialIcons
                                                                      .pencil,
                                                                  color: Colors
                                                                      .grey,
                                                                ),

如何正确迁移到 StreamBuilder?
我应该修改什么?

我的屏幕:

【问题讨论】:

    标签: flutter dart stream-builder flutter-futurebuilder


    【解决方案1】:

    基本上不可能直接因为FutureBuilder 采用Future 类型,而StreamBuilder 采用Stream 类型。

    Future 的工作方式就像 awaits 用于完成的事情(主要是远程 API 调用),然后当它完成时,它返回值,这就是结束。没有更多的互动。所以它只有一个返回值。

    但是,Stream 会不断返回或yields 值,直到您停止或dispose 它。所以它可以有无限数量的时间返回值。

    所以基本上如果你想在StreamBuilder中使用你的Future,它是行不通的。

    我不知道你到底想要什么,所以如果你还有其他问题,请通过 cmets 告诉我,但如果你想将 Future 变成 Stream,你可以使用 Stream.fromFuture(future)。但是它只有yields 一个事件并且将被关闭。所以我认为除非你有充分的理由使用StreamBuilder,否则我认为没有意义,尽管你只需要一个值。

    但是,如果您需要密切关注Future 提供的数据变化,那么从头开始创建Stream 可能是答案。

    Stream<Type> myStream() async* {
        while (true) 
        {
            final fetchedData = await yourFuture();
            yield fetchedData;
        }
    }
    

    上面的函数会生成一个Stream,它会不断调用你的Futureyield,直到它被释放为止。

    现在您可以将StreamBuilder 与您创建的Stream 一起使用。 StreamBuilder 的使用方法与FutureBuilder 的使用方法非常相似。希望大家参考这个documentation about StreamBuilder Class

    【讨论】:

    • 我更新了我的帖子。我想从 SharedPrefences (本地)而不是从 api 获取数据。但与此同时,也许我应该修改名称,例如或地址……我想改成 streambuilder 来解决这个问题,但我认为这不是正确的方法
    • 我如何在本地获取数据,同时我可以根据需要修改数据? @CelesKang
    • 基本上'fetch'被读取,'modify'被更新,对吗?所以只需从本地数据库中读取数据,如 SharedPreference 并在之后更新数据。我不确切知道您想要什么,但您不必在每次用户交互修改数据时更新本地数据库中的数据。只需从本地数据库中获取数据,并将它们存储在状态中,然后在该页面中完成所有操作后,在弹出或离开页面之前更新本地数据库中的数据。
    • excatlly如何在不离开页面的情况下在屏幕上更新数据?
    • 现在我的问题是下次登录时数据会更新@CelesKang
    猜你喜欢
    • 1970-01-01
    • 2015-02-27
    • 2013-07-22
    • 2011-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多