Flutter Builder & FutureBuilder & StreamBuilder组件

Flutter Builder & FutureBuilder & StreamBuilder组件

Builder组件

Builder组件起闭包作用,可以限制期使用范围。

问题

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

    @override
    Widget build(BuildContext context) {
        return Scaffold(
            appBar: AppBar(
                title: const Text("Builder组件"),
            ),
            body: Center(
                child: RaisedButton(
                    color: Colors.red,
                    textColor: Colors.white,
                    onPressed: () {
                        showSnackBar(context);
                    },
                    child: const Text('show SnackBar'),
                ),
            ),
        );
    }

    showSnackBar(BuildContext context) {
        const snackBar = SnackBar(content: Text('老孟'));
        Scaffold.of(context).showSnackBar(snackBar);
    }
}

点击按钮后,会提示异常信息:Scaffold.of() called with a context that does not contain a Scaffold.

这是因为你传入的BuildContext是当前parent Widget的,不是Scaffold的,所以会报错。

解决

可以借助Builder组件解决。

@override
Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
            title: const Text("Builder组件"),
        ),
        body: Builder(
            builder: (context) {
                return Center(
                    child: RaisedButton(
                        color: Colors.red,
                        textColor: Colors.white,
                        onPressed: () {
                            showSnackBar(context);
                        },
                        child: const Text('show SnackBar'),
                    ),
                );
            }
        ),
    );
}

FutureBuilder组件

展示异步任务状态,当有一个Future异步任务需要展示给用户时,可以使用FutureBuilder组件来实现。

在这里插入图片描述

final Future<dynamic> _futureSuccess = Future.delayed(const Duration(seconds: 3), () {
    return "成功了";
});
final Future<dynamic> _futureError = Future.delayed(const Duration(seconds: 3), () {
    return Future.error("失败了");
});

String _msg = "加载中";
String _msg2 = "加载中";

FutureBuilder(
    future: _futureSuccess,
    builder: (context, snapshot) {
        late Widget widget;
        if (snapshot.connectionState == ConnectionState.done) {
            if (snapshot.hasError) {
                widget = const Icon(Icons.error, color: Colors.red, size: 50);
                _msg = snapshot.error.toString();
            } else {
                if (snapshot.hasData) {
                    _msg = snapshot.data.toString();
                } else {
                    _msg = "无数据";
                }
                widget = const Icon(Icons.check_circle, color: Colors.green, size: 50);
            }
        } else {
            widget = const CircularProgressIndicator();
            _msg = "加载中";
        }
        return Container(
            height: 100,
            width: 100,
            decoration: BoxDecoration(
                border: Border.all(color: Colors.grey),
                borderRadius: const BorderRadius.all(Radius.circular(10)),
            ),
            child: Padding(
                padding: const EdgeInsets.all(8.0),
                child: Column(
                    children: [
                        widget,
                        Text(_msg),
                    ],
                ),
            ),
        );
    },
),
FutureBuilder(
    future: _futureError,
    builder: (context, snapshot) {
        late Widget widget;
        if (snapshot.connectionState == ConnectionState.done) {
            if (snapshot.hasError) {
                widget = const Icon(Icons.error, color: Colors.red, size: 50);
                _msg2 = snapshot.error.toString();
            } else {
                widget = const Icon(Icons.check_circle, color: Colors.green, size: 50);
                _msg2 = snapshot.data.toString();
            }
        } else {
            widget = const CircularProgressIndicator();
            _msg2 = "加载中";
        }
        return Container(
            height: 100,
            width: 100,
            decoration: BoxDecoration(
                border: Border.all(color: Colors.grey),
                borderRadius: const BorderRadius.all(Radius.circular(10)),
            ),
            child: Padding(
                padding: const EdgeInsets.all(8.0),
                child: Column(
                    children: [
                        widget,
                        Text(_msg2),
                    ],
                ),
            ),
        );
    },
)

StreamBuilder组件

StreamBuilder组件用于异步接收数据更新组件,与FutureBuilder不同的地方在于StreamBuilder可以接收多个异步操作。

在这里插入图片描述

late StreamController<dynamic> _streamController;

@override
void initState() {
    _streamController = StreamController();
    super.initState();
}

@override
void dispose() {
    _streamController.close();
    super.dispose();
}

Column(
    children: [
        StreamBuilder(
            stream: _streamController.stream,
            builder: (BuildContext context, AsyncSnapshot<dynamic> snapshot) {
                if (snapshot.hasError) {
                    return const Text("失败");
                } else {
                    if (snapshot.hasData) {
                        return Text("有数据 ${snapshot.data}");
                    } else {
                        return const Text("无数据");
                    }
                }
            },
        ),
        ElevatedButton(
            onPressed: () {
                _streamController.add("hello StreamBuilder");
            },
            child: const Text("发送数据"),
        ),
    ],
)
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值