Flutter流处理插件streamful的使用

Flutter流处理插件streamful的使用

简介

streamful 是一组用于处理流(streams)的 widgets 和工具。它可以帮助开发者更方便地管理流的状态和UI更新。

特性

StreamedLoading

StreamedLoading 是一个圆形加载指示器,根据一个表示加载状态的布尔流来显示加载动画。

使用方法

StreamedLoading(
  stream: _loadingController.stream, // 加载状态流
  color: Colors.blue, // 指示器颜色
  strokeWidth: 4.0, // 指示器宽度
);

Loading Mixin

Loading 混入类为类添加了一个 BehaviorSubject<bool>,以便轻松处理表示加载状态的流。

使用方法

class MyClass with Loading {
  void startLoading() {
    loadStart(); // 开始加载
  }

  void stopLoading() {
    loadStop(); // 结束加载
  }

  bool get isLoading => subject.value; // 获取当前加载状态
}

StreamWidget

StreamWidget 是对 StreamBuilder 的封装,允许定义:

  • onData: (data) {} 回调,当流有数据时返回要显示的 Widget。
  • onError: (error) {} 回调,当流有错误时返回要显示的 Widget。
  • onLoad: widget 当流既没有数据也没有错误时返回的 Widget。

使用方法

StreamWidget<String?>(
  stream: bloc.data,
  onData: (data) => Text(data!), // 数据回调
  onError: (error) => Text(error.toString()), // 错误回调
  onLoad: StreamedLoading(
    stream: bloc.isLoading,
    color: _color,
    strokeWidth: _strokeWidth,
  ), // 加载状态指示器
);

完整示例

示例代码

import 'package:example/bloc.dart';
import 'package:flutter/material.dart';
import 'package:streamful/streamful.dart';

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

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Streamful Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(title: 'Flutter Streamful Demo'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  final String? title;

  MyHomePage({Key? key, this.title}) : super(key: key);

  [@override](/user/override)
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  Color? _color = Colors.blue;
  double _strokeWidth = 4.0;

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text(widget.title!)),
      body: Padding(
        padding: EdgeInsets.all(16.0),
        child: _buildContent(),
      ),
    );
  }

  Widget _buildContent() {
    return Column(
      children: [
        Container(
          alignment: Alignment.centerLeft,
          child: Text(
            'Streamful',
            style: TextStyle(fontWeight: FontWeight.bold, fontSize: 22.0),
          ),
        ),
        Padding(
          padding: const EdgeInsets.only(bottom: 8.0),
          child: _buildColorPicker(),
        ),
        Padding(
          padding: const EdgeInsets.only(bottom: 8.0),
          child: _buildStrokeSizer(),
        ),
        Padding(
          padding: const EdgeInsets.only(bottom: 8.0),
          child: _buildActionButtons(),
        ),
        StreamWidget<String?>(
          stream: bloc.data,
          onData: (data) => Text(data!),
          onError: (error) => Text(error.toString()),
          onLoad: StreamedLoading(
            stream: bloc.isLoading,
            color: _color,
            strokeWidth: _strokeWidth,
          ),
        ),
      ],
    );
  }

  Widget _buildColorPicker() {
    return Row(
      children: [
        Expanded(
          child: Padding(
            padding: const EdgeInsets.only(right: 8.0),
            child: Text('Select a color'),
          ),
        ),
        Expanded(
          child: DropdownButton<Color>(
            isExpanded: true,
            value: _color,
            items: _colors,
            onChanged: (color) {
              setState(() {
                _color = color;
              });
            },
          ),
        ),
      ],
    );
  }

  List<DropdownMenuItem<Color>> get _colors {
    Map<String, Color> colors = {
      'Blue': Colors.blue,
      'Red': Colors.red,
      'Orange': Colors.orange,
      'Green': Colors.green,
    };

    List<DropdownMenuItem<Color>> _list = [];

    colors.forEach((key, value) {
      _list.add(
        DropdownMenuItem(child: Text(key), value: value),
      );
    });

    return _list;
  }

  Widget _buildStrokeSizer() {
    return Row(
      children: [
        Expanded(
          child: Padding(
            padding: const EdgeInsets.only(right: 8.0),
            child: Text('Set the stroke width'),
          ),
        ),
        Expanded(
          child: Slider(
            min: 1,
            max: 10,
            value: _strokeWidth,
            onChanged: (value) {
              setState(() {
                _strokeWidth = value;
              });
            },
          ),
        ),
      ],
    );
  }

  Widget _buildActionButtons() {
    return Row(
      children: [
        ElevatedButton(
          onPressed: () {
            bloc.getData();
          },
          child: Text('Success'),
        ),
        Spacer(),
        ElevatedButton(
          onPressed: () {
            bloc.getError();
          },
          child: Text('Error'),
        ),
      ],
    );
  }
}

更多关于Flutter流处理插件streamful的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter流处理插件streamful的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


Streamful 是一个用于 Flutter 的流处理插件,它提供了一种简洁的方式来处理异步数据流。通过 Streamful,你可以轻松地管理 StreamStreamController,并且可以更好地组织和维护你的代码。

1. 安装 Streamful

首先,你需要在 pubspec.yaml 文件中添加 streamful 插件的依赖:

dependencies:
  flutter:
    sdk: flutter
  streamful: ^0.1.0  # 请检查最新版本

然后运行 flutter pub get 来安装依赖。

2. 基本使用

Streamful 提供了 StreamfulWidgetStreamfulBuilder 来帮助你管理流数据。

使用 StreamfulWidget

StreamfulWidget 是一个 StatefulWidget,它可以帮助你管理一个 Stream。你可以在 createStream 方法中返回一个 Stream,然后在 build 方法中使用 StreamBuilder 来构建 UI。

import 'package:flutter/material.dart';
import 'package:streamful/streamful.dart';

class MyStreamfulWidget extends StreamfulWidget<String> {
  [@override](/user/override)
  Stream<String> createStream() {
    return Stream.periodic(Duration(seconds: 1), (count) => 'Count: $count');
  }

  [@override](/user/override)
  Widget build(BuildContext context, AsyncSnapshot<String> snapshot) {
    if (snapshot.connectionState == ConnectionState.waiting) {
      return CircularProgressIndicator();
    } else if (snapshot.hasError) {
      return Text('Error: ${snapshot.error}');
    } else {
      return Text('Data: ${snapshot.data}');
    }
  }
}

void main() {
  runApp(MaterialApp(
    home: Scaffold(
      body: MyStreamfulWidget(),
    ),
  ));
}

使用 StreamfulBuilder

StreamfulBuilder 是一个 Widget,它允许你在构建 UI 时直接使用 Stream。你可以通过 stream 参数传递一个 Stream,然后在 builder 方法中根据 AsyncSnapshot 来构建 UI。

import 'package:flutter/material.dart';
import 'package:streamful/streamful.dart';

class MyHomePage extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      body: StreamfulBuilder<String>(
        stream: Stream.periodic(Duration(seconds: 1), (count) => 'Count: $count'),
        builder: (context, snapshot) {
          if (snapshot.connectionState == ConnectionState.waiting) {
            return CircularProgressIndicator();
          } else if (snapshot.hasError) {
            return Text('Error: ${snapshot.error}');
          } else {
            return Text('Data: ${snapshot.data}');
          }
        },
      ),
    );
  }
}

void main() {
  runApp(MaterialApp(
    home: MyHomePage(),
  ));
}

3. 使用 StreamfulController

StreamfulController 是一个扩展了 StreamController 的类,它提供了更多便捷的方法来管理流。

import 'package:flutter/material.dart';
import 'package:streamful/streamful.dart';

class MyHomePage extends StatefulWidget {
  [@override](/user/override)
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final StreamfulController<String> _controller = StreamfulController();

  [@override](/user/override)
  void dispose() {
    _controller.close();
    super.dispose();
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        children: [
          StreamfulBuilder<String>(
            stream: _controller.stream,
            builder: (context, snapshot) {
              if (snapshot.connectionState == ConnectionState.waiting) {
                return CircularProgressIndicator();
              } else if (snapshot.hasError) {
                return Text('Error: ${snapshot.error}');
              } else {
                return Text('Data: ${snapshot.data}');
              }
            },
          ),
          ElevatedButton(
            onPressed: () {
              _controller.add('Button Pressed!');
            },
            child: Text('Press Me'),
          ),
        ],
      ),
    );
  }
}

void main() {
  runApp(MaterialApp(
    home: MyHomePage(),
  ));
}
回到顶部