【问题标题】:how to show two widgets one after another within some time interval in dart如何在飞镖的某个时间间隔内一个接一个地显示两个小部件
【发布时间】:2021-09-04 19:26:01
【问题描述】:

我试图在 2 秒的时间间隔内一个接一个地显示两个小部件。

在这里,我首先尝试显示文本小部件,并在两秒的时间间隔后将其更改为点小部件。

我试过了,但我做不到。我被困在如何一个接一个地返回两个小部件。

代码:

 Widget _getNumberWidget(bool hasHighlight, Color color, String text) {
    final textStyle = context.appThemeData.passcodeFieldStyle.numberTextStyle.textStyle.copyWith(color: color);
    return Container(
      height: 35,
      alignment: Alignment.bottomCenter,
      child: FittedBox(
        fit: BoxFit.fitHeight,
        child: text.isEmpty ? _getDotWidget(hasHighlight, color, text) : _showChar(hasHighlight, color, text),
      ),
    );
  }

     Widget _showChar(bool hasHighlight, Color color, String text) {
        final textStyle = context.appThemeData.passcodeFieldStyle.numberTextStyle.textStyle.copyWith(color: color);
          AppText(
            text: text,
            style: context.appThemeData.passcodeFieldStyle.numberTextStyle.copyWith(textStyle: textStyle),
          );
        
        sleep(const Duration(seconds: 2));
        return _getDotWidget(hasHighlight, color, text);
      }

如果我返回 Apptext,那么剩余的两行代码将变为死代码。任何人都可以建议我如何做到这一点。谢谢

【问题讨论】:

    标签: flutter dart future flutter-widget


    【解决方案1】:

    使用state,定义变量:

    bool _showDotWidget = false;
    

    Future.delayed代替sleep

    Widget _showChar(bool hasHighlight, Color color, String text) {
      if (_showDotWidget)
         return _getDotWidget(hasHighlight, color, text);
      else {
        Future.delayed(Duration(seconds:2), () {
          setState({
            _showDotWidget = true;
          });
        });
        final textStyle = context.appThemeData.passcodeFieldStyle.numberTextStyle.textStyle.copyWith(color: color);
          return AppText(
            text: text,
            style: context.appThemeData.passcodeFieldStyle.numberTextStyle.copyWith(textStyle: textStyle),
          );
      }
    }
    

    【讨论】:

    • 它正在返回应用程序文本并且不显示点小部件
    • 请显示构建方法代码,您调用_showChar的地方
    【解决方案2】:

    使用Future.delayed 检查我的简单实现,它会在 5 秒后触发 setState 以设置一个值 (isElapsed=true)。

    class _ShowWidgetsState extends State<ShowWidgets> {
      bool isElapsed = false;
    
      @override
      Widget build(BuildContext context) {
    
        //Delay for 5 seconds before setting 
        //isElapsed to true
        Future.delayed(Duration(seconds: 5), () {
          print('Displaying');
          setState(() {
            isElapsed = true;
          });
        });
    
        return Scaffold(
          appBar: AppBar(
            title: Text('Show Widgets'),
          ),
          body: Column(
            crossAxisAlignment: CrossAxisAlignment.center,
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              ElevatedButton(
                onPressed: () {},
                child: Text('First Widget'),
              ),
              SizedBox(height: 10.0),
              Container(
                  alignment: Alignment.center,
                  //Use Visibility Widget to show
                  child: Visibility(
                    visible: isElapsed,
                    child: ElevatedButton(
                      child: Text('Second Widget'),
                      onPressed: () {},
                    ),
                  )),
            ],
          ),
        );
      }
    

    【讨论】:

      【解决方案3】:

      你可以像这样使用 FutureBuilder

      import 'package:flutter/material.dart';
      
      class ShowWidgetWithInterval extends StatelessWidget {
      
        Future<bool> _setInterval() async {
          await Future.delayed(Duration(seconds: 2));
          return true;
        }
      
        @override
        Widget build(BuildContext context) {
          return FutureBuilder(
            future: _setInterval(),
            builder: (context, intervalSnapshot) {
              if (!intervalSnapshot.hasData) {
                return Text('Widget 1');
              }
      
              return Text('Widget 2');
            },
          );
        }
      }
      

      【讨论】:

        【解决方案4】:

        您可以使用FutureBuilder 并在函数中自定义StatelessWidget

        FutureBuilder(
                future: Future.delayed(const Duration(seconds: 3)),
                builder: (c, s) => s.connectionState == ConnectionState.done
                    ?  Text("Dot widget with text: $text") 
                    // Pass here SizedBox.shrink(); in case you do not want to render anithing
                    : const Text("Dot widget is loading..."));
        

        完整代码重现:

        import 'package:flutter/material.dart';
        
        void main() => runApp(MyApp());
        
        class MyApp extends StatefulWidget {
          @override
          _MyAppState createState() => _MyAppState();
        }
        
        class _MyAppState extends State<MyApp> {
          String? text;
          @override
          Widget build(BuildContext context) {
            return MaterialApp(
              title: 'Material App',
              home: Scaffold(
                floatingActionButton: FloatingActionButton(
                  onPressed: () {
                    setState(() {
                      text = 'Some text';
                    });
                  },
                ),
                body: Center(
                    child: Container(
                      padding: const EdgeInsets.all(4),
                        color: Colors.lightGreen, child: NumberWidget(text: text))),
              ),
            );
          }
        }
        
        class NumberWidget extends StatelessWidget {
          final bool hasHighlight;
          final Color color;
          final String? text;
          const NumberWidget(
              {Key? key,
              this.hasHighlight = false,
              this.color = Colors.lightGreen,
              this.text})
              : super(key: key);
        
          //Helper function for a text variable.
          bool isEmpty(String? s) => s == null || s.trim().isEmpty;
        
          @override
          Widget build(BuildContext context) {
            if (isEmpty(text)) {
              return const Text("Text is empty");
            }
            return FutureBuilder(
                future: Future.delayed(const Duration(seconds: 3)),
                builder: (c, s) => s.connectionState == ConnectionState.done
                    ?  Text("Dot widget with text: $text") 
                    // Pass here SizedBox.shrink(); in casde you do not want to render anithing
                    : const Text("Dot widget is loading..."));
          }
        }
        

        结果:

        【讨论】:

          猜你喜欢
          • 2021-11-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-11-10
          • 2021-12-21
          • 1970-01-01
          • 2019-12-01
          • 2020-05-05
          相关资源
          最近更新 更多