如何正确实现 StreamBuilder 颤振

时间:2021-05-29 10:42:55

标签: flutter dart stream-builder flutter-futurebuilder

我是 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?
我应该修改什么?

我的屏幕:

enter image description here

1 个答案:

答案 0 :(得分:0)

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

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

但是,Stream 会不断返回或yield s 值,直到您停止或dispose 它。所以它可以有无限多个时间返回值。

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

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

但如果您需要随时关注 Future 提供的数据的变化,从头开始制作 Stream 可能是答案。

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

上面的函数生成一个 Stream,它不断调用您的 FutureyieldFuture 的值进行处理,直到它被处理。

现在您可以将 StreamBuilder 与您制作的 Stream 一起使用。 StreamBuilder 的使用方法与 FutureBuilder 的使用方法非常相似。希望您参考此documentation about StreamBuilder Class