original

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

text

Asynchronous interaction may require an ideal opportunity to summarize. Occasionally, some values may be issued before the end of the period. In Dart, you can create a capacity that returns a Stream, which can emit some value while the asynchronous process is active. Suppose you need to construct a widget in Flutter based on a snapshot of a Stream, then there is a widget called StreamBuilder.

In this blog, we will explore StreamBuilder in Flutter. We will also implement a demo program and show you how to use StreamBuilder in your Flutter application.

introduce:

StreamBuilder can listen to the public stream, and return widgets and capture a snapshot of the obtained stream information. The stream maker put forward two arguments.

A stream

Builder, which can change multiple components in the stream into widgets

Stream is like a line. When you enter a value from one end and a listener from the other end, the listener will get that value. A stream can have multiple listeners, and the load of these listeners can get the pipeline, and the pipeline will get the same value. How to place values on the stream is achieved by using a stream controller. The flow builder is a widget that can change user-defined objects into flows.

builder:

To use StreamBuilder, you need to call the following constructor:
const StreamBuilder({
Key? key,
Stream<T>? stream,
T? initialData,
required AsyncWidgetBuilder<T> builder,
})

In fact, you need to create a Stream and pass it as a stream contention. Then, at this point, you need to pass an AsyncWidgetBuilder, which can be used to construct widgets that rely on Stream snapshots.

parameter:

Here are some parameters of StreamBuilderare:
  • Key? key : The widget key, used to control how the widget is replaced by another widget
  • Stream<T>? stream : A stream whose snapshot can be obtained through the generator function
  • T? initialData : This data will be used to make an initial snapshot
  • required AsyncWidgetBuilder<T> builder : The generation process is used by this generator

How to implement the code in the dart file:

You need to implement it in your code separately:

Let's create a stream:

The following function returns a Stream that generates one number per second. You need to use the async * keyword to create a stream. To emit a value, you can use the yield keyword followed by the value to be emitted.

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

From that point on, pass it as a stream parameter

StreamBuilder<int>(
stream: generateNumbers,
// other arguments
)
Let's create an AsyncWidgetBuilder

The constructor expects you to pass a naming contention builder of type AsyncWidgetBuilder. This is a function with two parameters, their types are BuildContext and AsyncSnapshot \< t>. Subsequent boundaries (including the current snapshot) can be used to determine what should be presented.

To create this function, you first need to understand AsyncSnapshot. AsyncSnapshot is an unchanging description of the latest communication using asynchronous computing. In this unique situation, it solves the latest communication with Stream. The latest snapshot of the stream can be obtained through the AsyncSnapshot property. One of the attributes you may need to use is connectionState. This enumeration converts the current associated state to asynchronous calculation. In this special case, this asynchronous calculation is 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 also has a property called hasError, which can be used to check whether the snapshot contains a non-empty error value. If the latest result of the asynchronous activity fails, the hasError value will be valid. In order to obtain information, first, you can check whether the snapshot contains information by obtaining its hasData property. If the Stream effectively releases any non-null values, then the hasData property will be valid. Then, at this point, you can get information from the data attributes of AsyncSnapshot.

Because of the values of the above attributes, you can calculate what should be displayed on the screen. In the code below, when the connectionState value is waiting, a CircularProgressIndicator will be displayed. When connectionState is changed to active or done, you can check the snapshot for errors or information. The construction function is called Flutter pipeline inspection. Therefore, it will get a subgroup of snapshots related to time. This means that if the Stream emits some values at actually similar times, some of the values may not be passed to the builder.

Enumerations have some possible values:
  • \> none: None: Not associated with any asynchronous calculation. If the stream is empty, it may happen
  • \> waiting: Waiting: Associated with asynchronous calculation and waiting for collaboration. In this context, it implies that the flow is not yet complete
  • \> active: active: associated with active asynchronous calculations. For example, if a Stream has returned any value, but it is not over yet
  • \> done:> Done: Associated with the completed asynchronous calculation. In this context, it implies that the flow has been completed
Set initial data:

You can choose to pass a worth as the initialData parameter, this parameter will be used until Stream sends out a. If the passed value is not empty, then when the connectionState is waiting, the hasData property will first be true in any event

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

To display the initial data while the connectionState is waiting, you should adjust if snapshot.connectionState == connectionState.waiting, and then adjust the block in the code above.

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),
        ),
      ),
    ],
  );
}

When we run the application, we should get the screen output like the screen video below.

Code File:

Password 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}');
              }
            },
          ),
        ),
      ),
    );
  }
}

Conclusion:

In this article, I have briefly introduced the basic structure of StreamBuilder; you can modify this code according to your choice. This is my little introduction to StreamBuilder On User Interaction, which is working with Flutter.


© Cat brother

Past

Open source

GetX Quick Start

https://github.com/ducafecat/getx_quick_start

News client

https://github.com/ducafecat/flutter_learn_news

strapi manual translation

https://getstrapi.cn

WeChat discussion group ducafecat

Series collection

Translation

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

Open source project

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

Dart programming language basics

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

Getting started with Flutter zero foundation

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

Flutter actual combat from scratch news client

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

Flutter component development

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


独立开发者_猫哥
666 声望126 粉丝