在 Flutter 中关闭错误对话框:不起作用,它会弹出父窗口小部件或当前页面(删除当前页面)

问题描述 投票:0回答:1

我在做项目时遇到了一个问题。 我正在尝试通过 API 将医生注册到数据库。当我单击注册按钮时,我希望它显示一个加载对话框以等待 API 响应,然后如果发生错误,我想显示一个错误对话框。

  • 我使用provider通过Consumer通知监听者,而不是使用FutureBuilder。
  • 我制作了加载和错误对话框自定义无状态小部件。
  • 我想在调用 API 时显示加载对话框,并在发生错误时显示错误对话框,并通过将业务层与表示层分离来实现这一点。

但是当我尝试关闭(单击错误对话框上的“确定”按钮)错误对话框时,它会从父小部件或当前页面弹出,它会删除该页面。

以下是我尝试过的示例。

1- 用户提供商;

  • 我尝试用 Builder 小部件包装错误对话框,但它不起作用。
  • 在首页,使用Consumer的部分不能使用
    showDialog()
    方法或
    showSnackbar
    方法,它需要返回一个小部件。

此链接是要运行和编辑的 Dartpad 示例:https://dartpad.dev/?id=87bd2aae2f549c10201c02996fd1e10f

以下是我尝试过的示例。

1- 主要方法和主页:

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

void main() {
  runApp(
    ChangeNotifierProvider(
      create: (context) => UserProvider(),
      child: MaterialApp(
        title: 'Flutter Demo',
        theme: ThemeData(
          primarySwatch: Colors.blue,
        ),
        initialRoute: '/',
        routes: {
          '/': (context) => const MyHomePage(title: 'Flutter Demo Home Page'),
        },
      ),
    ),
  );
}

class MyHomePage extends StatefulWidget {
  final String title;

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

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  late UserProvider _userProvider;
  @override
  Widget build(BuildContext context) {
    _userProvider = Provider.of<UserProvider>(context, listen: true);
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Consumer<UserProvider>(
              builder: (context, notifire, child) {
                if (notifire.state == NotifireState.initial) {
                  return const Text(
                    'Click To Register',
                    style: TextStyle(
                      fontSize: 16,
                      height: 1.3,
                    ),
                  );
                } else if (notifire.state == NotifireState.loading) {
                  return const LoadingDialog(message: 'Wait for Response...');
                } else {
                  //return const RegistrationSucceededDialog();
                  return const RegistrationErrorDialog(
                    errorMessage: 'problem Message',
                  );
                }
              },
            ),
            const SizedBox(
              height: 20,
            ),
            ElevatedButton(
              onPressed: () {
                //Provider.of<UserProvider>(context, listen: true).registerUser('User');
                _userProvider.registerUser('User');
              },
              child: const Text(
                'Register',
                style: TextStyle(
                  fontSize: 22,
                  fontWeight: FontWeight.w400,
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

2- 用户提供商:

enum NotifireState { initial, loading, loaded }

class UserProvider extends ChangeNotifier {
  //final AbstractHttpUserRepo _httpUserService = HttpUserService();

  NotifireState _state = NotifireState.initial;
  NotifireState get state => _state;
  void _setState(NotifireState state) {
    _state = state;
    notifyListeners();
  }

  // // One User
  late User _user;
  User get user => _user;

  void _setUser(
    User user,
  ) {
    _user = user;
  }

  // // Multiple Users
  late User _users;
  User get users => _users;

  void _setUsers(
    User users,
  ) {
    _users = users;
  }

  Future<void> registerUser(
    User user,
  ) async {
    _setState(NotifireState.loading);

    // // call the api to register
    // final userCreateResult = await _httpUserService.create(user);
    await Future.delayed(const Duration(seconds: 3));

    // // Set the user
    // _setDoctor(userCreateResult);

    _setState(NotifireState.loaded);
  }
}

3-错误对话框无状态小部件:

class RegistrationErrorDialog extends StatelessWidget {
  final String errorMessage;
  const RegistrationErrorDialog({
    Key? key,
    required this.errorMessage,
  }) : super(key: key);

  final TextStyle _buttonsTextStyle = const TextStyle(
    fontSize: 17,
    fontWeight: FontWeight.w400,
  );

  final TextStyle _textStyle = const TextStyle(
    height: 1.3,
    fontSize: 16.7,
    fontWeight: FontWeight.w500,
  );

  @override
  Widget build(BuildContext context) {
    return AlertDialog(
      shape: RoundedRectangleBorder(
        borderRadius: BorderRadius.circular(10),
      ),
      insetPadding: const EdgeInsets.symmetric(horizontal: 15),
      icon: const Icon(
        Icons.error_rounded,
        size: 45,
        color: Colors.red,
      ),
      iconPadding: const EdgeInsets.only(top: 5, bottom: 10),
      actionsPadding: const EdgeInsets.only(right: 15, bottom: 10),
      content: Column(
        mainAxisSize: MainAxisSize.min,
        mainAxisAlignment: MainAxisAlignment.start,
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text(
            'An Error Occurred While Registrating The Accout:',
            style: _textStyle,
          ),
          const SizedBox(height: 20),
          Text(
            errorMessage,
            // softWrap: false,
            style: _textStyle,
          ),
        ],
      ),
      actions: [
        TextButton(
          child: Text(
            'Ok',
            style: _buttonsTextStyle,
          ),
          onPressed: () {
            Navigator.of(context).pop();
          },
        ),
      ],
    );
  }
}

4- 和加载对话框:

class LoadingDialog extends StatelessWidget {
  final String message;
  const LoadingDialog({
    Key? key,
    required this.message,
  }) : super(key: key);

  final TextStyle _textStyle = const TextStyle(
    height: 1.3,
    fontSize: 16.7,
    fontWeight: FontWeight.w500,
  );

  @override
  Widget build(BuildContext context) {
    return AlertDialog(
      shape: RoundedRectangleBorder(
        borderRadius: BorderRadius.circular(10),
      ),
      insetPadding: const EdgeInsets.symmetric(horizontal: 15),
      iconPadding: const EdgeInsets.only(top: 5, bottom: 10),
      actionsPadding: const EdgeInsets.only(right: 15, bottom: 10),
      content: Column(
        mainAxisSize: MainAxisSize.min,
        mainAxisAlignment: MainAxisAlignment.center,
        crossAxisAlignment: CrossAxisAlignment.center,
        children: [
          const CircularProgressIndicator(),
          const SizedBox(height: 10),
          Text(
            message,
            style: _textStyle,
          ),
        ],
      ),
    );
  }
}
flutter dart dialog loading
1个回答
0
投票

您无法将小部件返回为

AlertDialog
。这不是如何使用和显示对话框。

阅读这个官方示例:https://api.flutter.dev/flutter/material/AlertDialog-class.html

你必须使用

showDialog
方法,然后使用其中的
AlertDialog

showDialog<String>(
   context: context,
   builder: (BuildContext context) => AlertDialog(
     title: const Text('AlertDialog Title'),
     content: const Text('AlertDialog description'),
     actions: <Widget>[]

showDialog
是未来的方法。和
Navigator.pop
将关闭该对话框。 如果您在没有该方法的情况下关闭
AlertDialog
,则您将使用空堆栈导航路线。这就是为什么然后没有显示。

© www.soinside.com 2019 - 2024. All rights reserved.