首页 > 解决方案 > 如何让 Flutter 对话框消失?

问题描述

我一直在试图弄清楚如何让我的颤动对话框消失。我已经尝试了一切,在方法完成处理之前,我所做的任何事情都不会摆脱它。

背景:制作一个应用程序,允许用户从他们的设备中选择图像,然后使用用户定义的名称将其压缩(在 AlertDialog 中收到,不会立即消失)。

我试图让 AlertDialog 立即消失的事情:

  1. Navigator.of(context).pop()
  2. Navigator.pop(上下文)
  3. Navigator.of(context, rootNavigator: true).pop()
  4. 试图确保异步调用该方法后不会阻塞

在 pubspec.yaml 中添加了导入

path_provider: ^2.0.2
archive: ^3.1.2
file_picker: ^4.0.3

下面的代码:

import 'dart:io';

import 'package:archive/archive_io.dart';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
import 'package:path/path.dart';
import 'package:path_provider/path_provider.dart';

void main() {
  runApp(const MyApp());
}

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

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        // This is the theme of your application.
        //
        // Try running your application with "flutter run". You'll see the
        // application has a blue toolbar. Then, without quitting the app, try
        // changing the primarySwatch below to Colors.green and then invoke
        // "hot reload" (press "r" in the console where you ran "flutter run",
        // or simply save your changes to "hot reload" in a Flutter IDE).
        // Notice that the counter didn't reset back to zero; the application
        // is not restarted.
        primarySwatch: Colors.blue,
      ),
      home: const HomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class HomePage extends StatefulWidget {
  final String title;

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

  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  final GlobalKey<FormState> _formKey = GlobalKey<FormState>();

  late final Directory _uploadsDir;

  @override
  void initState() {
    super.initState();
    _init();
  }

  @override
  void dispose() async {
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: () => _importFilesSelected(context),
          child: const Text("Select Images"),
        ),
      ),
    );
  }

  void _init() async {
    Directory dir = await getApplicationDocumentsDirectory();
    _uploadsDir = await Directory(join(dir.path, "uploads")).create(recursive: true);
  }

  void _importFilesSelected(BuildContext context) async {
    final BuildContext buildContext = context;

    FilePickerResult? result = await FilePicker.platform.pickFiles(
        dialogTitle: "Select File(s) to Import",
        allowMultiple: true,
        type: FileType.custom,
        allowedExtensions: ['jpg', 'png'],
        onFileLoading: (FilePickerStatus status) {
          if (status == FilePickerStatus.picking) {
            showDialog(
              context: buildContext,
              barrierDismissible: false,
              builder: (BuildContext context) {
                return Dialog(
                  child: Padding(
                    padding: const EdgeInsets.all(12.0),
                    child: Row(
                      mainAxisSize: MainAxisSize.min,
                      children: const [
                        CircularProgressIndicator(),
                        SizedBox(width: 10.0,),
                        Text("Processing Files..."),
                      ],
                    ),
                  ),
                );
              },
            );
          } else {
            Navigator.pop(buildContext);
          }
        },
        withData: false
    );

    _processResult(result, buildContext);
  }

  void _processResult(FilePickerResult? result, BuildContext buildContext) async {
    if (result != null) {
      String? zipFilename = await _showGetZipFileNameDialog(buildContext);
      print("zipFileName: $zipFilename");
      _processImagesIntoZip(result, zipFilename!);
    }
  }

  void _processImagesIntoZip(FilePickerResult result, String zipFilename) async {
    String zipPath = join(_uploadsDir.path, zipFilename);

    final encoder = ZipFileEncoder();
    encoder.create(zipPath);

    for (PlatformFile file in result.files) {
      encoder.addFile(File(file.path!));
    }
  }

  Future<String?> _showGetZipFileNameDialog(BuildContext context) {
    String? zipFilename;

    return showDialog<String>(
        context: context,
        barrierDismissible: false,
        builder: (context) {
          return AlertDialog(
            title: const Text("Save As"),
            content: Form(
              key: _formKey,
              child: TextFormField(
                decoration: const InputDecoration(
                  labelText: "Save As:",
                ),
                validator: (val) {
                  return val!.isEmpty ? "Please fill out filename" : null;
                },
                onSaved: (val) => zipFilename = "${val!}.zip",
              ),
            ),
            actions: [
              TextButton(
                child: const Text("Cancel"),
                onPressed: () {
                  Navigator.pop(context);
                },
              ),
              TextButton(
                child: const Text("OK"),
                onPressed: () {
                  if (_formKey.currentState!.validate()) {
                    _formKey.currentState!.save();

                    // Remove the Dialog from the screen
                    Navigator.pop(context, zipFilename);
                  }
                },
              ),
            ],
          );
        }
    );
  }
}

标签: flutterdart

解决方案


我有类似的问题已修复使用

Navigator.pop(context);

推荐阅读