Skip to content

Stream1

Stream-1

Code

//main.dart
import 'package:flutter/material.dart';
import 'stream.dart';

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

class MyApp extends StatelessWidget {
// This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Stream',
      theme: ThemeData(
        primarySwatch: Colors.deepPurple,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: StreamHomePage(),
    );
  }
}

class StreamHomePage extends StatefulWidget {
  @override
  _StreamHomePageState createState() => _StreamHomePageState();
}

class _StreamHomePageState extends State<StreamHomePage> {
  Color? bgColor;
  ColorStream? colorStream;

  @override
  void initState() {
    colorStream = ColorStream();
    changeColor();
    super.initState();
  }

  changeColor() async {
    await for (var eventColor in colorStream!.getColors()) {
      setState(() {
        bgColor = eventColor;
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text('Stream'),
        ),
        body: Container(
          decoration: BoxDecoration(color: bgColor),
        ));
  }
}

程式碼說明

這段程式碼是在 Flutter 中使用 Dart 語言撰寫的,它定義了一個名為 MyApp 的無狀態小部件和一個名為 StreamHomePage 的有狀態小部件。

MyApp 是應用程式的根小部件,它返回一個 MaterialApp 小部件,並設置了應用程式的主題和首頁。

StreamHomePage 是一個有狀態小部件,它的狀態由 _StreamHomePageState 類別管理。在 _StreamHomePageState 類別中,我們定義了一個 ColorStream 物件和一個 Color 物件。在 initState 方法中,我們初始化 ColorStream 物件並呼叫 changeColor 方法。changeColor 方法是一個異步方法,它從 ColorStream 物件中讀取顏色並更新 bgColor。

在 build 方法中,我們創建一個 Scaffold 小部件,該小部件包含一個 AppBar 和一個 Container。Container 的背景顏色由 bgColor 決定。

該方法的核心是 await for 命令。這是一個異步 for 迴圈,用於迴圈訪問流的事件。基本上,它就像一個 for(或 for each)迴圈,但不是反覆運算一組數據(如清單),而是異步地監聽流中的每個事件。從那裡,我們調用 setState 方法來更新 bgColor 屬性。

還可以把

 await for (var eventColor in colorStream!.getColors()) {
      setState(() {
        bgColor = eventColor;
      });
    }

替換成

colorStream?.getColors().listen((eventColor) {
      setState(() {
        bgColor = eventColor;
      });
    });

listen 和 await for 之間的主要區別在於,當迴圈後有一些代碼時,listen 將允許繼續執行,而 await for 將停止執行,直到stream完成。
在這個特定的應用程式中,我們永遠不會停止收聽流,但您應該始終在流完成其任務時關閉它。為此,您可以使用 close() 方法


//stream.dart
import 'package:flutter/material.dart';
import 'dart:async';

class ColorStream {
  Stream<Color> getColors() async* {
    final List<Color> colors = [
      Colors.blueGrey,
      Colors.amber,
      Colors.deepPurple,
      Colors.lightBlue,
      Colors.teal
    ];
    yield* Stream.periodic(Duration(seconds: 1), (int t) {
      int index = t % 5;
      return colors[index];
    });
  }
}

程式碼說明

這段程式碼是在 Dart 語言中定義一個名為 ColorStream 的類別,該類別用於生成一個顏色的串流。這個串流每秒鐘發出一種顏色,並在五種顏色之間循環。

在 ColorStream 類別中,我們定義了一個 colorStream 的成員變數,它是一個 Stream 物件。然後,我們定義了一個名為 getColors 的方法,該方法是一個異步生成器(由 async* 標記)。這個方法生成一個 Stream<Color> 物件,該物件每秒鐘發出一種顏色。

在 getColors 方法中,我們首先定義了一個名為 colors 的列表,該列表包含五種顏色。然後,我們使用 yield* 關鍵字來將控制權交給另一個串流,該串流由 Stream.periodic 方法生成。這個方法創建一個每秒鐘發出一個值的串流,該值由一個函數計算得出,該函數接受一個整數(從 0 開始,每次增加 1),並返回 colors 列表中的一種顏色。

在 Dart 和 Flutter 中,你使用 async 表示 futures,使用 async*(帶星號 *)表示流。如前所述,流和 future 之間的主要區別在於返回的事件數:Future 只有 1 個,Stream 為 0 個。當您將函數標記為 async* 時,您正在建立稱為產生器函數的特定類型的函數,因為它會生成一系列值(流)。
為了在 async* 方法中返回流,請使用 yield* 語句。稍微簡化一下,您可能會認為 yield* 是一個返回語句,但有很大的區別:yield* 不會結束函數。

Stream.periodic() 是創建流的構造函數。steam以您在作為參數傳遞的值中指定的時間間隔發出事件。在我們的代碼中,stream將每秒發出一個值。

Last update : 13 novembre 2024
Created : 13 novembre 2024

Comments

Comments