对话框不断弹出

发布于 2025-02-09 01:51:43 字数 1945 浏览 1 评论 0原文

我正在使用Flutter来构建应用程序,并在第一次运行应用程序时尝试显示输入对话框。为此,我使用共享的首选项库。但是,当我打开应用程序时,无论是第一次,每次都会显示对话框。另外,当我在输入框中键入一个字母时,另一个对话框在上一封信的前面打开。我已附上以下代码:

 class HomeMenu extends StatefulWidget {
  const HomeMenu({Key? key}) : super(key: key);

  @override
  State<HomeMenu> createState() => _HomeMenuState();
 }

class _HomeMenuState extends State<HomeMenu> with TickerProviderStateMixin {
  late TabController _controller;
  TextEditingController textController = TextEditingController();

  var newLaunch;

  Future<void> showDialogIfFirstLoaded(BuildContext thisContext) async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    bool _newLaunch = prefs.getBool('newLaunch') ?? true;
    newLaunch = _newLaunch;
    if (newLaunch) {
      showDialog(
        context: thisContext,
        builder: (BuildContext context) {
          return AlertDialog(
            content: TextField(
              controller: textController,
              onChanged: (value) =>
                  setState(() => name = textController.text),
            ),
            actions: <Widget>[
              TextButton(
                child: const Text('OK'),
                onPressed: () {
                  Navigator.pop(thisContext);
                  prefs.setBool(newLaunch, false);
                },
              ),
            ],
          );
        },
      );
    }
  }

  @override
  void initState() {
    super.initState();
    _controller = TabController(length: 3, vsync: this);
  }

  @override
  Widget build(BuildContext context) {
    Future.delayed(Duration.zero, () => showDialogIfFirstLoaded(context));
    return Scaffold(
      appBar: AppBar(
        bottom: TabBar(
          controller: _controller,
          tabs: tabs,
        ),
      ),
      body: TabBarView(
        controller: _controller,
        children: [
           null
        ],
      ),
    );
  }
}

I am using Flutter to build an app and trying to show an input dialogue box when app is run for the first time. For this I use shared preferences library. However, when I open the app, the dialogue box is shown every time regardless if it is the first time or not. Also, as I type a single letter in the input box, another dialogue box opens up in front of the previous one. I have attached the code below:

 class HomeMenu extends StatefulWidget {
  const HomeMenu({Key? key}) : super(key: key);

  @override
  State<HomeMenu> createState() => _HomeMenuState();
 }

class _HomeMenuState extends State<HomeMenu> with TickerProviderStateMixin {
  late TabController _controller;
  TextEditingController textController = TextEditingController();

  var newLaunch;

  Future<void> showDialogIfFirstLoaded(BuildContext thisContext) async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    bool _newLaunch = prefs.getBool('newLaunch') ?? true;
    newLaunch = _newLaunch;
    if (newLaunch) {
      showDialog(
        context: thisContext,
        builder: (BuildContext context) {
          return AlertDialog(
            content: TextField(
              controller: textController,
              onChanged: (value) =>
                  setState(() => name = textController.text),
            ),
            actions: <Widget>[
              TextButton(
                child: const Text('OK'),
                onPressed: () {
                  Navigator.pop(thisContext);
                  prefs.setBool(newLaunch, false);
                },
              ),
            ],
          );
        },
      );
    }
  }

  @override
  void initState() {
    super.initState();
    _controller = TabController(length: 3, vsync: this);
  }

  @override
  Widget build(BuildContext context) {
    Future.delayed(Duration.zero, () => showDialogIfFirstLoaded(context));
    return Scaffold(
      appBar: AppBar(
        bottom: TabBar(
          controller: _controller,
          tabs: tabs,
        ),
      ),
      body: TabBarView(
        controller: _controller,
        children: [
           null
        ],
      ),
    );
  }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

感情洁癖 2025-02-16 01:51:43

您正在调用在构建方法中加载的showdialogifferst,在textfiled on Change方法中,您正在调用SetState。每次调用SetState构建方法再次重建时,它都会调用每个SetState上的ShowDialogiffirst。

我不知道您的要求,但是在TextField的Onchange方法中致电SetState并不好。您可以使用 alofollow noreferrer“> alofollow noreistenablebuilder 每种char类型的文本类型

如果您只想打开一次对话框,则

,然后创建一种方法以获取它是否是第一次启动,如果是,则请致电Showdialogiffirstloaded方法。有关更多详细信息,请参见下面的代码 -

   @override
      void initState() {
        super.initState();
        _controller = TabController(length: 3, vsync: this);
        _isFirstLaunch();
      }
    
    _isFirstLaunch()async{
       final prefs = await SharedPreferences.getInstance();
       final bool? isfirstLaunch = prefs.getBool('first_launch');
       if(!isfirstLaunch ?? true){
        await prefs.setBool('first_launch', true);
        showDialogIfFirstLoaded(context);
       }

and update your build method like this -


 @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        bottom: TabBar(
          controller: _controller,
          tabs: tabs,
        ),
      ),
      body: TabBarView(
        controller: _controller,
        children: [
           null
        ],
      ),
    );
  }

you are calling showDialogIfFirstLoaded in build method, and on TextFiled onChange method you are calling setState. Every time you call setState build method re-build again and it calling showDialogIfFirstLoaded on every setState.

I don't know your requirement but it not good to call setState in onChange method of TextField. You can use ValueListenableBuilder if you require to update some part of UI on every single char type in text filed

If you want's to open that dialog only one time then create a method to get whether it's first launch or not and if yes then call showDialogIfFirstLoaded method.

For more details see below code -

   @override
      void initState() {
        super.initState();
        _controller = TabController(length: 3, vsync: this);
        _isFirstLaunch();
      }
    
    _isFirstLaunch()async{
       final prefs = await SharedPreferences.getInstance();
       final bool? isfirstLaunch = prefs.getBool('first_launch');
       if(!isfirstLaunch ?? true){
        await prefs.setBool('first_launch', true);
        showDialogIfFirstLoaded(context);
       }

and update your build method like this -


 @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        bottom: TabBar(
          controller: _controller,
          tabs: tabs,
        ),
      ),
      body: TabBarView(
        controller: _controller,
        children: [
           null
        ],
      ),
    );
  }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文