【问题标题】:How to use StreamBuilder to perform network requests with different values如何使用 StreamBuilder 执行不同值的网络请求
【发布时间】:2021-05-26 06:15:55
【问题描述】:

我正在使用FutureBuilder 小部件根据未来counter 的值渲染Text,当我单击浮动操作按钮时,我再次使用不同的值调用未来。但是我需要在单击按钮后执行 setState 以刷新 UI,这对于屏幕上的几个小部件来说很好,但调用 setState 也会重建其他小部件。


class _MyHomePageState extends State<MyHomePage> {
  Future counter;

  @override
  void initState() {
    super.initState();
    counter = counterFuture(4);
  }

  //This would be a network request with a specific value
  Future<int> counterFuture(int i) async {
    return await Future.value(i);
  }

  _changeCounter(int i) {
    setState(() {
      counter = counterFuture(i);
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Demo'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            FutureBuilder<int>(
              future: counter,
              builder: (context, snapshot) {
                if (snapshot.hasData) {
                  return Text(snapshot.data.toString());
                }
                return Text('loading');
              },
            ),
             ...other widgets
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        //tap button to request with a different value
        onPressed: () => _changeCounter(9),
      ),
    );
  }
}

我的问题是如何使用 Streams 和 StreamBuilder 仅渲染和更新 Text 小部件来实现这一点?

【问题讨论】:

    标签: flutter dart stream-builder flutter-futurebuilder


    【解决方案1】:

    您可以使用 StreamController 轻松做到这一点。 查看下面的代码 sn-p:

    class _MyHomePageState extends State<MyHomePage> {
      int counter;
      StreamController controller = StreamController<int>();
    
      @override
      void initState() {
        initialize();
        super.initState();
      }
    
      initialize() async {
        counter = await counterFuture(4);
        controller.add(counter);
      }
    
      @override
      void dispose() {
        controller.close();
       super.dispose();
      }
    
      //This would be a network request with a specific value
      Future<int> counterFuture(int i) async {
        return await Future.value(i);
      }
    
      _changeCounter(int i) async {
        counter = await counterFuture(i);
        controller.add(counter);
      }
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: Scaffold(
            appBar: AppBar(
              title: Text('Demo'),
            ),
            body: Center(
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  StreamBuilder<int>(
                    stream: controller.stream,
                    builder: (context, snapshot) {
                      if (snapshot.hasData) {
                        return Text(snapshot.data.toString());
                      }
                      return Text('loading');
                    },
                  ),
                ],
              ),
            ),
            floatingActionButton: FloatingActionButton(
               //tap button to request with a different value
             onPressed: () => _changeCounter(9)),
          ),
        );
      }
    }
    

    【讨论】:

    • 但是我需要 streamBuilder 来根据 Future 进行更新,这就是我在示例中使用 counterFuture 的原因。
    • 好的。我对我的答案进行了编辑。看看吧。
    猜你喜欢
    • 1970-01-01
    • 2020-01-24
    • 1970-01-01
    • 2023-02-02
    • 2021-12-31
    • 1970-01-01
    • 2020-03-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多