I am having a String
that is supposed to be returned after clicking a button in a Future
showModalBottomSheet
. Below is how i how i am implementing it and how it is working
onPressed: () async {
String? returnString = await showModalBottomSheet<String>(
context: context,
isDismissible: false,
builder: (ctx) {
return StatefulBuilder(builder: (ctx, setState) {
return Container(
margin: EdgeInsets.all(10),
padding: EdgeInsets.all(10),
child: ElevatedButton(
onPressed: (){
Navigator.pop(ctx, "This is return string bla bla bla");
},
child: Text("Click Me To Return"),
),
);
});
},
);
Logger().i("PrintReturnString: $returnString");
Logger().i("PrintReturnStringRunTimeType: ${returnString.runtimeType}");
}
But because i want to use this in several places and i did not want to repeat myself and rewrite the code every time in other classes that would be redundant i decided to try implementing this using a global method but its not working it just returns null instead of String
This is return string bla bla bla
Below is how i have tried implementing it using a method that i can call anywhere in the class
showReturnStringBottomSheet(ctx) async {
await showModalBottomSheet<String>(
context: ctx,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(top: Radius.circular(25))),
elevation: 5,
isDismissible: true,
isScrollControlled: true,
builder: (ctx) {
return StatefulBuilder(builder: (ctx, setState) {
return Container(
margin: EdgeInsets.all(10),
padding: EdgeInsets.all(10),
child: ElevatedButton(
onPressed: (){
Navigator.pop(ctx, "This is return string bla bla bla");
},
child: Text("Click Me To Return"),
),
);
});
});
}
Below is how i am calling the method
onPressed: () async {
String? returnString = await showReturnStringBottomSheet(context);
}
Is there something that i am doing wrong because its just working when i put the method directly insde onPressed
but it stops working when i use a global method
CodePudding user response:
You can pass the String
outside your modal bottom sheet for example:
class _MyHomePageState extends State<MyHomePage> {
String? text;
Future<void> _openBottomSheet() async {
final value = await _myBottomSheet();
setState(() {
text = value;
});
}
Future<String?> _myBottomSheet() async {
String? value;
await showModalBottomSheet<void>(
context: context,
builder: (context) => Center(
child: TextButton(
onPressed: () {
value = 'Hello world!';
Navigator.pop(context);
},
child: const Text('Say hello!'),
),
),
);
return value;
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: text?.isNotEmpty == true
? Text(text!)
: const Text('Bottom sheet example'),
),
body: Center(
child: TextButton(
onPressed: _openBottomSheet,
child: const Text('Open bottom sheet'),
),
),
);
}
}
CodePudding user response:
showModalBottomSheet
is an async
method so you should wait for it then it makes your showReturnStringBottomSheet
a future
function ,Try this:
Future<String?> showReturnStringBottomSheet(ctx) async {
var result = await showModalBottomSheet<String>(
context: ctx,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(top: Radius.circular(25))),
elevation: 5,
isDismissible: true,
isScrollControlled: true,
builder: (ctx) {
return StatefulBuilder(builder: (ctx, setState) {
return Container(
margin: EdgeInsets.all(10),
padding: EdgeInsets.all(10),
child: ElevatedButton(
onPressed: () {
Navigator.pop(ctx, "This is return string bla bla bla");
},
child: Text("Click Me To Return"),
),
);
});
});
return result;
}
and use it like this:
onPressed: () async {
String? returnString = await showReturnStringBottomSheet(context);
if(returnString != null){
print("returnString = $returnString");
}
}
CodePudding user response:
The problem is you forgot to return here:
showReturnStringBottomSheet(ctx) async {
await showModalBottomSheet<String>(
change it to :
//Add Future<String?> here to make code cleaner
Future<String?> showReturnStringBottomSheet(ctx) {
return showModalBottomSheet<String>(