I try to select a file in file picker and process the situation when a wrong file type was selected. So the code throws a _wrongFileTypeDialog
which gives options to cancel the dialog or select file again. The problem is when I choose wrong file type several times then if I want to cancel the dialog I need to press cancel
button several times (actualy I need to press it the same number of times the wrong file type was chosen).
If I put Navigator.pop(context);
before _getFile(context);
then I get another more complicated error Looking up a deactivated widget's ancestor is unsafe. At this point the state of the widget's element tree is no longer stable.
A starting point - a button which runs _getFile(context)
to open a file picker.
Future<void> _getFile(BuildContext context) async {
final FlutterDocumentPickerParams params = FlutterDocumentPickerParams(
allowedFileExtensions: ['txt'],
);
String errorMessage;
final String path =
await FlutterDocumentPicker.openDocument(params: params).catchError((dynamic e) {
errorMessage = e.toString();
debugPrint(errorMessage);
});
if (path == null) {
if (errorMessage != null && errorMessage.contains('Picked file extension mismatch!')) {
_wrongFileTypeDialog(context);
return;
}
return;
}
}
void _wrongFileTypeDialog(BuildContext context) {
showDialog(
context: context,
builder: (BuildContext context) => AlertDialog(
title: const Text('Wrong file type'),
actions: [
TextButton(
onPressed: () => Navigator.pop(context),
child: const Text('Cancel'),
),
TextButton(
onPressed: () {
// Navigator.pop(context);
_getFile(context);
},
child: const Text('Choose file'),
),
],
),
);
}
Obviously I could run this to close the dialog
while (Navigator.canPop(context)) {
Navigator.pop(context);
}
but it's more like a temporary workaround.
CodePudding user response:
I try to select a file in file picker and process the situation when a wrong file type was selected. So the code throws a _wrongFileTypeDialog which gives options to cancel the dialog or select file again. The problem is when I choose wrong file type several times then if I want to cancel the dialog I need to press cancel button several times (actualy I need to press it the same number of times the wrong file type was chosen).
You're calling the _wrongFileTypeDialog
recursively each time you choose wrong file type:
Future<void> _getFile(BuildContext context) async {
...
if (path == null) {
if (errorMessage != null && errorMessage.contains('Picked file extension mismatch!')) {
_wrongFileTypeDialog(context);
return;
}
return;
}
}
and _getFile
will be called each time you press the button:
void _wrongFileTypeDialog(BuildContext context) {
...
onPressed: () {
_getFile(context);
},
...
}
So, it will keep calling themeself.
If I put Navigator.pop(context); before _getFile(context); then I get another more complicated error Looking up a deactivated widget's ancestor is unsafe. At this point the state of the widget's element tree is no longer stable.
When you're calling the Navigator.pop(context)
in the following code:
void _wrongFileTypeDialog(BuildContext context) {
showDialog(
context: context,
builder: (BuildContext context) => AlertDialog(
...
actions: [
...
onPressed: () {
Navigator.pop(context);
_getFile(context);
},
...
),
],
),
);
}
You're popping the AlertDialog with its context. So, when _getFile(context);
is executed, the context is already gone.
You need to use context
from the parent of the method. So, change the parameter context
name so that it not overshadowed by AlertDialog context:
void _wrongFileTypeDialog(BuildContext ctx) {
showDialog(
context: context,
builder: (BuildContext context) => AlertDialog(
...
actions: [
...
onPressed: () {
Navigator.pop(context);
_getFile(ctx);
},
...
),
],
),
);
}