日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網(wǎng)站首頁 編程語言 正文

Presenting?Streams?in?Flutter小技巧_Android

作者:程序員界的小學生 ? 更新時間: 2023-01-05 編程語言

正文

如果我想要做一個組件,每秒更新時間, 最開始的想法就是使用StatefulWidget, 然后每秒調用一下setState方法刷新數(shù)據(jù)

能不能換成使用StatelessWidget呢? 可以的,不過用Stream來實現(xiàn)。

先創(chuàng)建一個AsyncSnapshot的拓展

extends PresentAsyncSnapshot<E> on AsyncSnapshot<E> {
    Widget present({
        required BuildContext context,
        Widget Function(BuildContext context)? onNone,
        Widget Function(BuildContext context, E data)? onData,
        Widget Function(BuildContext context, Object error, StackTrace stackTrace)? onError,
        Widget Function(BuildContext context)? onDoneWitNeitherDataNorError,
        Widget FUnction(BuildContext context)? onWaiting,
    }) {
        switch (connectionState) {
            case ConnectionState.none:
                return onNone?.call(context) ?? const SizedBox.shrink();
            case ConnectionState.waiting:
                return onWaiting?.call(context) ?? const CircularProgressIndicator();
            case ConnectionState.active: //future在done狀態(tài)產(chǎn)生值,但是stream在active狀態(tài)下就已經(jīng)持續(xù)產(chǎn)生值了
            case ConnectionState.done:
                if (hasError) {
                    return onError?.call(context, error!, stackTrace!) ?? const SizedBox.shrink();
                } else if (hasData) {
                    return onData?.call(context, data as E) ?? const SizedBox.shrink();
                } else {
                    reutrn onDoneWitNeitherDataNorError?.call(context) ?? const SizedBox.shrink();
                }
        }
    }
}

創(chuàng)建一個stream,每秒產(chǎn)生一個值

Stream<String> getDataTime() => Stream.perioodic(
    const Duration(seconds: 1),
    (_) => DateTime.now().toIso8601string(),
);

創(chuàng)建Stream拓展

為了方便使用,我又創(chuàng)建了一個Stream的拓展,為了內部使用上面寫的PresentAsyncSnapshot拓展

extension PresentStream<E> on Stream<E> {
    Widget present({
        Widget Function(BuildContext context)? onNone,
        Widget Function(BuildContext context, E data)? onData,
        Widget Function(BuildContext context, Object error, E data)? onData,
        Widget Function(BuildContext context)? onDoneWitNeitherDataNorError,
        Widget Function(BuildContext context)? onWaiting.
    }) {
        return StreamBuilder<E>(
            stream: this,
            builder: (context, snapshot) => snapshot.present(
                context: context,
                onNone: onNone,
                onData: onData,
                onError: onError,
                onDoneWitNeitherDataNorError: onDoneWItNeitherDataNorError,
                onWaiting: onWaiting,
            ),
        );
    }
}

下面來測試一下,只需要在任何Stream的地方 調用present()就能很簡單的使用,可以傳入你想要調用的任何方法的回調。

class HomePage extends StatelessWidget {
    const HomePage({Key? key}): super(key: key);
    @override
    Widget build(BuildContext context) {
        return Scaffold(
            body: SafeArea(
                child: getDateTime().present(
                    onData: (_, dateTime) => Text(dateTime),
                ),
            ),
        );
    }
}

大功告成,下面看一下結果

原文鏈接:https://juejin.cn/post/7174637935168323644

欄目分類
最近更新