Loading progress indicator is not displaing while making async call - flutter

I try to use https://pub.dev/packages/loading_overlay to display a simple loading overlay while making an async call in form.
class AccountFormState extends State<AccountForm> {
bool _loading = false;
override
Widget build(BuildContext context) {
return LoadingOverlay(
child: Form(
...
),
isLoading: _loading,
);
where in the form there is a
ElevatedButton(
onPressed: () async {
if (_formKey.currentState.validate()) {
bool loginResult = await webService.testLoginSite(); // an async call
print('loginResult = $loginResult');
if (loginResult == true) {
Scaffold.of(context)
.showSnackBar(SnackBar(content: Text('successfull')));
}
}
},
child: Text('Check login'),
),
The problem is that the LoadingOverlay does not show overlay loading indicatow while making an async call in the ElevatedButton.
Why does it not work?

You need to setState _isLoading before and after webService.testLoginSite()
ElevatedButton(
onPressed: () async {
if (_formKey.currentState.validate()) {
setState(() {
_isLoading = true;
});
bool loginResult = await webService.testLoginSite(); // an async call
print('loginResult = $loginResult');
setState(() {
_isLoading = false;
});
if (loginResult == true) {
Scaffold.of(context)
.showSnackBar(SnackBar(content: Text('successfull')));
}
}
},
child: Text('Check login'),
),

Related

Flutter, getting value from showTimePicker not working

I am trying to displayed time selected from showTimePicker dialogue but after getting the value it becomes null again.
after debugging, it seems like the value returned from future function expried or something.
after the widgets onPress function it is back to null.
ElevatedButton(
child: const Text('Time'),
onPressed: () async {
vTimeSelected = await getTimeSelected(context);
setState(() {
// vStrToRndr = vTimeSelected.toString();
//print(vStrToRndr);
});
},
),
ElevatedButton(
child: const Text('Solid'),
onPressed: () {
setState(() {
vDetail.solid = !vDetail.solid;
});
},
),
],
),
),
if (vDetail.wet == true) Text('Nappy wet'),
if (vDetail.solid == true) Text('Nappy Solid'),
Text('Time: $vTimeSelected'),
[7:35 PM]
Future<TimeOfDay?> getTimeSelected(BuildContext context) async {
TimeOfDay vTime = TimeOfDay(hour: 0, minute: 0);
TimeOfDay? newTime =
await showTimePicker(context: context, initialTime: vTime);
return newTime;
//print($newTime);
}
//thanks for any help
Text('Time: $vTimeSelected') //<---- this is displaying null
You can follow this code structure. Make sure to declare variable outside the build method.
class TS extends StatefulWidget {
const TS({super.key});
#override
State<TS> createState() => _TSState();
}
class _TSState extends State<TS> {
TimeOfDay? vTimeSelected;
#override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton: FloatingActionButton(onPressed: () async {
vTimeSelected = await getTimeSelected(context);
setState(() {});
}),
body: Text("${vTimeSelected}"),
);
}
}

CircularProgressIndicator not stopping while moving back

Created a demo for understanding future..
I have taken two screen....Using Future.delayed I am forwarding to next screen in 5 seconds with CircularProgressIndicator...but when I move to back..it still showing CircularProgressbar...
What should I correct my code?
here is my code
class _MyHomePageState extends State<MyHomePage> {
#override
void initState() {
// TODO: implement initState
super.initState();
}
bool isloading = false;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Async demo'),
),
body: isloading == true
? Center(child: CircularProgressIndicator())
: Center(
child: TextButton(
child: Text('Pressed'),
onPressed: () {
setState(() {
isloading = true;
});
Future.delayed(Duration(seconds: 5), () {
Navigator.of(context)
.push(MaterialPageRoute(builder: (context) {
return NextScreen();
}));
isloading = false;
});
},
),
),
);
}
}
What should I correct my code?
Wrap the second assignment of isloading to false inside setState (just as you did when setting to true). Something like the following:
onPressed: () {
setState(() {
isloading = true;
});
Future.delayed(Duration(seconds: 5), () {
Navigator.of(context).push(MaterialPageRoute(builder: (context) {
return NextScreen();
}));
setState(() {
isloading = false;
});
});
},
you need to use setState when you are assign variable = false
For that do as below
replace this
isloading = false;
with
setState(() {
isloading = false;
});

Flutter Modular Mobx - Observable doesn't update inside of onpress

I am new with Flutter and I am having a problem. I'm using mobx. In my view I have a button and inside of this button, I am waiting for the showDialog property to change in order to show the dialog view . However, within onpress the showdialog does not work. Is there any other way to do this?
My controller
#observable
bool showDialog = false;
#action
Future callLoginService() async {
await Future.delayed(Duration(seconds: 6));
showDialog = true;
}
view
Observer(
builder: (_) {
return Center(
child: RaisedButton(
child: Text("TESTE"),
onPressed: () async {
controller.callLoginService();
if (controller.showDialog) {
final action = await InfoDialogView.showAlertDialog(
context, "Try again", 'Invalid user');
if (action == DialogAction.abort) {
controller.showDialog = false;
}
}
},
),
);
},
),
This is because your onPressed method is asynchronous but you haven't used 'await' keyword ahead of controller.callLoginService().
Observer(
builder: (_) {
return Center(
child: RaisedButton(
child: Text("TESTE"),
onPressed: () async {
await controller.callLoginService(); //put await for calling asynchronous methods
if (controller.showDialog) {
final action = await InfoDialogView.showAlertDialog(
context, "Try again", 'Invalid user');
if (action == DialogAction.abort) {
controller.showDialog = false;
}
}
},
),
);
},
),

Button onPressed async method with 2 setState

I can't figure out why 2 setState in async onPressed method causing error
Unhandled Exception: setState() called after dispose():
_LoginScreenState#0eb2c(lifecycle state: defunct, not mounted)
Here is my code
RaisedButton(
child: Text('Login'),
onPressed: emailController.text == "" || passwordController.text == ""
? null
: () async {
setState(() {
_isLoading = true;
});
SharedPreferences prefs =
await SharedPreferences.getInstance();
prefs.setString('email', emailController.text);
try {
await Provider.of<Auth>(context, listen: false)
.signIn(emailController.text, passwordController.text);
} on HttpException catch (error) {
exceptionAlertDialog(context, error.toString());
} catch (error) {
exceptionAlertDialog(context, error.toString());
}
setState(() {
_isLoading = false;
});
},
)
once isLoading is true I display spinner.. Nothing extraordinary
body: Container(
alignment: Alignment.center,
child: _isLoading
? Center(child: CircularProgressIndicator())
: ListView(
children: <Widget>[textSection(), buttonSection()],
),
),
Everything works fine if I comment out those 2 set state in the button onPressed.
try to put isLoading to dispose
#override
void dispose() {
_isLoading = false;
super.dispose();
}

How to use image_picker in flutter

I am confused about how to use image_picker, this is how I use it in my application (like in many tutorials):
class AddDialogState extends State<AddDialog> {
File galleryFile;
Widget _onlyStatus() {
getLocalImage() async {
var _galleryFile = await ImagePicker.pickImage(
source: ImageSource.gallery
};
setState(() {
galleryFile = _galleryFile;
});
print(_galleryFile.path);
}
return Column(
........
FlatButton.icon(
onPressed: () {
getLocalImage();
}
)
)
}
#override
Widget build(BuildContext context) {
// fullscreen dialog
.........
body: _onlyStatus()
}
}
The problem was, the above code doesn't start ImagePicker, when i click the FlatButton, the above code just produce an error the getter 'path' was called on null, it doesn't start any new activity related to gallery, so what's wrong with my code?
Actually pickImage() is deprecated now. So you have to use ImagePicker.getImage(source: ImageSource.gallery)
Click here for more
void getImage(ImageSource imageSource) async {
PickedFile imageFile = await picker.getImage(source: imageSource);
if (imageFile == null) return;
File tmpFile = File(imageFile.path);
final appDir = await getApplicationDocumentsDirectory();
final fileName = basename(imageFile.path);
tmpFile = await tmpFile.copy('${appDir.path}/$fileName');
setState(() {
_image = tmpFile;
});
}
The code also store image file in device directory. Path pacakage is also used.
Here is my example you only need to call the SelectionItem and pass the required parameters and it's done, also it includes support for Android and iOS.
class SelectionItem {
String text;
GestureTapCallback action;
SelectionItem({
this.text,
this.action,
});
}
Widget _getOptionWidget(SelectionItem item) {
return SimpleDialogOption(
onPressed: item.action,
child: Text(item.text),
);
}
Widget _getCupertinoOptionWidget(SelectionItem item) {
return CupertinoActionSheetAction(
onPressed: item.action,
child: Text(item.text),
);
}
showSelector(
BuildContext context, {
String title,
List<SelectionItem> actions,
}) {
bool isAndroid = Injector.instance.platform == Platform.ANDROID;
if (isAndroid) {
final items = actions.map((action) => _getOptionWidget(action)).toList();
return SimpleDialog(
title: Text(title),
children: items,
);
} else {
final items =
actions.map((action) => _getCupertinoOptionWidget(action)).toList();
return Column(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
CupertinoActionSheet(
title: Text(title),
actions: items,
cancelButton: CupertinoActionSheetAction(
onPressed: () {
NavigationUtils.pop(context);
},
child: Text("Cancel"),
),
),
],
);
}
}
your showDialog should be something like this:
Container(
width: 300,
height: 300,
child: GestureDetector(
onTap: () {
showDialog(
context: context,
builder: (BuildContext context) => showSelector(
context,
"Select",
actions: [
SelectionItem(
"Camera",
action: () {
getImage(ImageSource.camera);
Navigator.of(context).pop();
},
),
SelectionItem(
"Gallery",
action: () {
getImage(ImageSource.gallery);
Navigator.of(context).pop();
},
)
],
),
);
},
),
)
Here is my code for image_picker: ^0.8.4+4 (flutter 2.8.1)
bool hasImage = false;
File? image;
Future getImage(ImageSource source) async {
try {
final image = await ImagePicker().pickImage(source: source);
if (image == null) return;
final imageTemporary = File(image.path);
setState(() {
this.image = imageTemporary;
hasImage = true;
});
} on PlatformException catch (e) {
debugPrint('Failed to pick image: $e');
}
}