Fultter中的FutureBuilder和StreamBuilder详解

2022年8月7日 1173点热度 0人点赞 0条评论

一、目标:使用StreamBuilder模拟实现每隔一秒返回从网络中获取的数据,并刷新页面。
效果图:
Fultter中的FutureBuilder和StreamBuilder详解插图

Stream.periodic构造,顾名思义,是用来创建流,在周期间隔反复广播事件。

<code>import &#039;package:flutter/material.dart&#039;;

main()=&gt;runApp(const MyApp());

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        appBar: AppBar(
          title: const Text(&quot;StreamBuilder&quot;),
          centerTitle: true,
        ),
        body: Center(
          child: StreamBuilder&lt;int&gt;(
              stream: _getNetWorkData(),
              builder: (BuildContext context, AsyncSnapshot&lt;int&gt; snapshot){
                if(snapshot.hasError){
                  return const Text(&quot;出错了&quot;);
                }
                switch(snapshot.connectionState){
                  case ConnectionState.none:
                    return const Text(&quot;没有 stream&quot;);
                  case ConnectionState.waiting:
                    return const Text(&quot;等待数据......&quot;);
                  case ConnectionState.active:
                    return Text(&quot;active: ${snapshot.data}&quot;);
                  case ConnectionState.done:
                    return const Text(&quot;Stream 已经关闭&quot;);
                }
              }),
        )
      ),
    );
  }
}

 Stream&lt;int&gt; _getNetWorkData() {
  return Stream.periodic(const Duration(seconds: 1),(i){
    return i;
  });
 }</code>

深入理解BuildStream,我们将要构建的应用程序的背景颜色会随着时间而变化。它还在屏幕中央显示递增的数字。我们可以通过按下浮动按钮来阻止这些无情的行为。
代码例子:

<code>import &#039;package:flutter/material.dart&#039;;
import &#039;dart:async&#039;;
import &#039;dart:math&#039;;

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

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      // Hide the debug banner
      debugShowCheckedModeBanner: false,
      title: &#039;KindaCode.com&#039;,
      theme: ThemeData(
        primarySwatch: Colors.indigo,
      ),
      home: const HomeScreen(),
    );
  }
}

class HomeScreen extends StatefulWidget {
  const HomeScreen({Key? key}) : super(key: key);

  @override
  State&lt;HomeScreen&gt; createState() =&gt; _HomeScreenState();
}

class _HomeScreenState extends State&lt;HomeScreen&gt; {
  final Stream _myStream =
      Stream.periodic(const Duration(seconds: 1), (int count) {
    return count;
  });

  // The subscription on events from _myStream
  late StreamSubscription _sub;

  // This number will be displayed in the center of the screen
  // It changes over time
  int _computationCount = 0;

  // Background color
  // In the beginning, it&#039;s indigo but it will be a random color later
  Color _bgColor = Colors.indigo;

  @override
  void initState() {
    _sub = _myStream.listen((event) {
      setState(() {
        _computationCount = event;

        // Set the background color to a random color
        _bgColor = Colors.primaries[Random().nextInt(Colors.primaries.length)];
      });
    });
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: _bgColor,
      appBar: AppBar(
        title: const Text(&#039;Lucklyの博客&#039;),
        backgroundColor: Colors.transparent,
      ),
      body: Center(
        child: Text(
          _computationCount.toString(),
          style: const TextStyle(fontSize: 150, color: Colors.white),
        ),
      ),
      // This button is used to unsubscribe the stream listener
      floatingActionButton: FloatingActionButton(
        child: const Icon(
          Icons.stop,
          size: 30,
        ),
        onPressed: () =&gt; _sub.cancel(),
      ),
    );
  }

  // Cancel the stream listener on dispose
  @override
  void dispose() {
    _sub.cancel();
    super.dispose();
  }
}</code>

二、目标:使用FutureBuilder构建,等待网络请求回来的数据,显示到页面,还没有拿到数据前,显示loading
效果图:
Fultter中的FutureBuilder和StreamBuilder详解插图1

<code>import 'package:flutter/material.dart';

main()=>runApp(const MyApp());

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        appBar: AppBar(
          title: const Text("FutureBuilder"),
          centerTitle: true,
        ),
        body: Center(
          child: FutureBuilder<String>(
              future: _getNetWorkData(),
              builder: (BuildContext context, AsyncSnapshot<String> snapshot){
                 if(snapshot.connectionState==ConnectionState.done){
                   if(snapshot.hasError){
                     return const Text("请求失败!");
                   }else{
                     return Text("content: ${snapshot.data}");
                   }
                 }else{
                   //请求未结束。显示loading
                   return const CircularProgressIndicator();
                 }
              }),
        )
      ),
    );
  }
}

 Future<String> _getNetWorkData() {
    return Future.delayed(const Duration(seconds: 1),(){
      return "从网络获取到的数据";
    });
 }</code>

小小调酒师

此刻打盹,你将做梦; 此刻学习,你将圆梦。 个人邮箱:shellways@foxmail.com

文章评论