天天看點

在 Flutter 中探索 StreamBuilder介紹:建造者:參數:如何實作 dart 檔案中的代碼:Code File:密碼檔案:結語:

[外鍊圖檔轉存失敗,源站可能有防盜鍊機制,建議将圖檔儲存下來直接上傳(img-LnRUZ45G-1630491413971)(https://ducafecat.tech/2021/09/01/translation/exploring-streambuilder-in-flutter/2021-09-01-17-37-55.png)]

原文

https://medium.com/flutterdevs/exploring-streambuilder-in-flutter-5958381bca67

正文

異步互動可能需要一個理想的機會來進行總結。偶爾,在周期結束之前可能會發出一些值。在 Dart 中,您可以建立一個傳回 Stream 的容量,該容量可以在異步程序處于活動狀态時發射一些值。假設您需要根據一個 Stream 的快照在 Flutter 中構造一個小部件,那麼有一個名為 StreamBuilder 的小部件。

在這個部落格中,我們将探索 Flutter 中的 StreamBuilder。我們還将實作一個示範程式,并向您展示如何在您的 Flutter 應用程式中使用 StreamBuilder。

介紹:

StreamBuilder 可以監聽公開的流,并傳回小部件和捕獲獲得的流資訊的快照。造溪者提出了兩個論點。

A stream

建構器,它可以将流中的多個元件更改為小部件

Stream 像一條線。當您從一端輸入值而從另一端輸入偵聽器時,偵聽器将獲得該值。一個流可以有多個偵聽器,這些偵聽器的負載可以獲得流水線,流水線将獲得等價值。如何在流上放置值是通過使用流控制器實作的。流建構器是一個小部件,它可以将使用者定義的對象更改為流。

建造者:

要使用 StreamBuilder,需要調用下面的構造函數:
const StreamBuilder({
Key? key,
Stream<T>? stream,
T? initialData,
required AsyncWidgetBuilder<T> builder,
})
           

實際上,您需要建立一個 Stream 并将其作為流争用傳遞。然後,在這一點上,您需要傳遞一個 AsyncWidgetBuilder,該 AsyncWidgetBuilder 可用于構造依賴于 Stream 快照的小部件。

參數:

下面是 StreamBuilderare 的一些參數:
  • Key? key

    : 小部件的鍵,用于控制小部件如何被另一個小部件取代
  • Stream<T>? stream

    : 一個流,其快照可以通過生成器函數獲得
  • T? initialData

    : 将利用這些資料制作初始快照
  • required AsyncWidgetBuilder<T> builder

    : 生成過程由此生成器使用

如何實作 dart 檔案中的代碼:

你需要分别在你的代碼中實作它:

讓我們建立一個流:

下面的函數傳回一個每秒生成一個數字的 Stream。你需要使用 async * 關鍵字來建立一個流。若要發出值,可以使用 yield 關鍵字後跟要發出的值。

Stream<int> generateNumbers = (() async* {
  await Future<void>.delayed(Duration(seconds: 2));

  for (int i = 1; i <= 10; i++) {
    await Future<void>.delayed(Duration(seconds: 1));
    yield i;
  }
})();
           

From that point onward, pass it as the stream argument

從那一點開始,把它作為流參數傳遞下去

StreamBuilder<int>(
stream: generateNumbers,
// other arguments
)
           
讓我們建立一個 AsyncWidgetBuilder

構造函數期望您傳遞一個類型為 AsyncWidgetBuilder 的命名争用建構器。這是一個有兩個參數的函數,它們的類型都是 BuildContext 和 AsyncSnapshot < t > 。後續的邊界(包含目前快照)可以用來确定應該呈現的内容。

要建立這個函數,首先需要了解 AsyncSnapshot。AsyncSnapshot 是使用異步計算的最新通信的不變描述。在這種獨特的情況下,它解決了與 Stream 的最新通信。可以通過 AsyncSnapshot 屬性擷取流的最新快照。您可能需要使用的屬性之一是 connectionState,這個枚舉将目前關聯狀态轉換為異步計算,在這種特殊情況下,這種異步計算就是 Steam。

StreamBuilder<int>(
  stream: generateNumbers,
  builder: (
      BuildContext context,
      AsyncSnapshot<int> snapshot,
      ) {
    if (snapshot.connectionState == ConnectionState.waiting) {
      return CircularProgressIndicator();
    } else if (snapshot.connectionState == ConnectionState.active
        || snapshot.connectionState == ConnectionState.done) {
      if (snapshot.hasError) {
        return const Text('Error');
      } else if (snapshot.hasData) {
        return Text(
            snapshot.data.toString(),
            style: const TextStyle(color: Colors._red_, fontSize: 40)
        );
      } else {
        return const Text('Empty data');
      }
    } else {
      return Text('State: ${snapshot.connectionState}');
    }
  },
),
           

AsyncSnapshot 還有一個名為 hasError 的屬性,可用于檢查快照是否包含非空錯誤值。如果異步活動的最新結果失敗,hasError 值将有效。為了擷取資訊,首先,您可以通過擷取其 hasData 屬性來檢查快照是否包含資訊,如果 Stream 有效地釋放了任何非空值,那麼 hasData 屬性将是有效的。然後,在這一點上,您可以從 AsyncSnapshot 的資料屬性擷取資訊。

由于上面屬性的值,您可以計算出應該在螢幕上呈現什麼。在下面的代碼中,當 connectionState 值正在等待時,将顯示一個 CircularProgressIndicator。當 connectionState 更改為 active 或 done 時,可以檢查快照是否有錯誤或資訊。建造函數稱為 Flutter 管道的檢測。是以,它将獲得一個與時間相關的快照子組。這意味着,如果在實際上相似的時間裡,Stream 發出了一些值,那麼一部分值可能沒有傳遞給建構器。

枚舉有一些可能的值:
  • > none: 無: 不與任何異步計算關聯。如果流為空,則可能發生
  • > waiting: 等待: 與異步計算關聯并等待協作。在這個上下文中,它暗示流還沒有完成
  • > active: 活躍的: 與活動的異步計算相關聯。例如,如果一個 Stream 已經傳回了任何值,但此時還沒有結束
  • > done: > 完成: 與結束的異步計算相關聯。在這個上下文中,它暗示流已經完成
設定初始資料:

您可以選擇傳遞一個 worth 作為 initialData 參數,這個參數将被利用,直到 Stream 發出 a。如果傳遞的值不為空,那麼當 connectionState 在等待時,hasData 屬性在任何事件中首先都将為 true

StreamBuilder<int>(
initialData: 0,
// other arguments
)
           

要在 connectionState 等待時顯示初始資料,應該調整 if snapshot.connectionState = = connectionState.waiting,然後調整上面代碼中的塊。

if (snapshot.connectionState == ConnectionState.waiting) {
  return Column(
    crossAxisAlignment: CrossAxisAlignment.center,
    mainAxisAlignment: MainAxisAlignment.center,
    children: [
      CircularProgressIndicator(),
      Visibility(
        visible: snapshot.hasData,
        child: Text(
          snapshot.data.toString(),
          style: const TextStyle(color: Colors._black_, fontSize: 24),
        ),
      ),
    ],
  );
}
           

當我們運作應用程式,我們應該得到螢幕的輸出像下面的螢幕視訊。

[外鍊圖檔轉存失敗,源站可能有防盜鍊機制,建議将圖檔儲存下來直接上傳(img-MPd0hgYR-1630491413973)(https://ducafecat.tech/2021/09/01/translation/exploring-streambuilder-in-flutter/demo.gif)]

Code File:

密碼檔案:

import 'package:flutter/material.dart';
import 'package:flutter_steambuilder_demo/splash_screen.dart';

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

class MyApp extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Splash(),
      debugShowCheckedModeBanner: false,
    );
  }
}

Stream<int> generateNumbers = (() async* {
  await Future<void>.delayed(Duration(seconds: 2));

  for (int i = 1; i <= 10; i++) {
    await Future<void>.delayed(Duration(seconds: 1));
    yield i;
  }
})();

class StreamBuilderDemo extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return _StreamBuilderDemoState ();
  }
}

class _StreamBuilderDemoState extends State<StreamBuilderDemo> {

  @override
  initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        automaticallyImplyLeading: false,
        title: const Text('Flutter StreamBuilder Demo'),
      ),
      body: SizedBox(
        width: double._infinity_,
        child: Center(
          child: StreamBuilder<int>(
            stream: generateNumbers,
            initialData: 0,
            builder: (
                BuildContext context,
                AsyncSnapshot<int> snapshot,
                ) {
              if (snapshot.connectionState == ConnectionState.waiting) {
                return Column(
                  crossAxisAlignment: CrossAxisAlignment.center,
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    CircularProgressIndicator(),
                    Visibility(
                      visible: snapshot.hasData,
                      child: Text(
                        snapshot.data.toString(),
                        style: const TextStyle(color: Colors._black_, fontSize: 24),
                      ),
                    ),
                  ],
                );
              } else if (snapshot.connectionState == ConnectionState.active
                  || snapshot.connectionState == ConnectionState.done) {
                if (snapshot.hasError) {
                  return const Text('Error');
                } else if (snapshot.hasData) {
                  return Text(
                      snapshot.data.toString(),
                      style: const TextStyle(color: Colors._red_, fontSize: 40)
                  );
                } else {
                  return const Text('Empty data');
                }
              } else {
                return Text('State: ${snapshot.connectionState}');
              }
            },
          ),
        ),
      ),
    );
  }
}
           

結語:

在本文中,我已經簡單介紹了 StreamBuilder 的基本結構; 您可以根據自己的選擇修改這段代碼。這是我對 StreamBuilder On User Interaction 的一個小小介紹,它正在使用 Flutter 工作。

© 貓哥

  • https://ducafecat.tech/
  • https://github.com/ducafecat
  • 微信群 ducafecat
  • b 站 https://space.bilibili.com/404904528

往期

開源

GetX Quick Start

https://github.com/ducafecat/getx_quick_start

新聞用戶端

https://github.com/ducafecat/flutter_learn_news

strapi 手冊譯文

https://getstrapi.cn

微信讨論群 ducafecat

系列集合

譯文

https://ducafecat.tech/categories/%E8%AF%91%E6%96%87/

開源項目

https://ducafecat.tech/categories/%E5%BC%80%E6%BA%90/

Dart 程式設計語言基礎

https://space.bilibili.com/404904528/channel/detail?cid=111585

Flutter 零基礎入門

https://space.bilibili.com/404904528/channel/detail?cid=123470

Flutter 實戰從零開始 新聞用戶端

https://space.bilibili.com/404904528/channel/detail?cid=106755

Flutter 元件開發

https://space.bilibili.com/404904528/channel/detail?cid=144262

Flutter Bloc

https://space.bilibili.com/404904528/channel/detail?cid=177519

Flutter Getx4

https://space.bilibili.com/404904528/channel/detail?cid=177514

Docker Yapi

https://space.bilibili.com/404904528/channel/detail?cid=130578