I'm a beginner and wanted to make a quick app where it shows how many times you have hit a button and later translate this knowledge of button interaction to making a calculator. I wrote some code but do not know what I should change to fix my mess-up. Specifically, when I click my button it does not show any change in the text. Here's my code:
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
Widget build(BuildContext context) {
return MaterialApp(title: "Ame's Application", home: MyHomePage());
}
}
class MyHomePage extends StatelessWidget {
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("App"),
backgroundColor: Colors.amber,
),
body: TextInputWidget());
}
}
class TextInputWidget extends StatefulWidget {
#override
_TextInputWidgetState createState() => _TextInputWidgetState();
}
class _TextInputWidgetState extends State<TextInputWidget> {
int count = 0;
increaseCount() {
setState(() {
count++;
});
}
#override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
Text("You have hit the button ${count} times"), SizedBox(height: 100,),
FloatingActionButton(
onPressed: increaseCount(), child: Text("Click"))
]
);
}
}```
You have to pass the reference of the function, not its return type so instead of:
FloatingActionButton(
onPressed: increaseCount(), child: Text("Click")
)
do this :
FloatingActionButton(
onPressed: increaseCount, child: Text("Click")
)
I also recommend you to set the return type of the increaseCount method to void (by default it is dynamic).
The problem comes with your FloatingActionButton. onPressed requires a callback that is called when the button is tapped.
When your method has no parameter as is the case here, you can do:
FloatingActionButton(onPressed: increaseCount, child: Text("Click")),
But, in general, you would do:
FloatingActionButton(onPressed: () => increaseCount(), child: Text("Click")),
That would also allow you to define more complex method such as one that increments your counter by x:
FloatingActionButton(onPressed: () => increaseCount(x), child: Text("Click")),
Related
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: "Basit ToDo Uygulaması",
home: Iskele(),
);
}
}
class Iskele extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("ToDo Uygulaması"),
),
body: AnaEkran(),
);
}
}
class AnaEkran extends StatefulWidget {
#override
_AnaEkranState createState() => _AnaEkranState();
}
class _AnaEkranState extends State<AnaEkran> {
TextEditingController t1 = TextEditingController();
List alisverisListesi = [];
elemanEkle() {
setState(() {
alisverisListesi.add(t1.text);
t1.clear();
});
}
elemanCikar() {
setState(() {
alisverisListesi.remove(t1.text);
t1.clear();
});
}
#override
Widget build(BuildContext context) {
return Container(
child: Column(
children: <Widget>[
Flexible(
child: ListView.builder(
itemCount: alisverisListesi.length,
itemBuilder: (context, siraNumarasi) => ListTile(
subtitle: Text("Marketten Alınacaklar"),
title: Text(alisverisListesi[siraNumarasi]),
),
),
),
TextField(
controller: t1,
),
RaisedButton(
onPressed: elemanEkle,
child: Text("Ekle"),
),
RaisedButton(
onPressed: elemanCikar,
child: Text("Çıkar"),
),
],
),
);
}
RaisedButton({required Function() onPressed, required Text child}) {}
}
**
main.dart
**
!!
I don't understand why I'm getting this error, can you help me? I am
trying to make a simple app in Flutter but I have this error in front
of me.
I don't understand why I'm getting this error, can you help me? I am
trying to make a simple app in Flutter but I have this error in front
of me.
Remove line 82: RaisedButton({required Function() onPressed, required Text child}) {}. I don't actually understand what this line is supposed to do, can you explain that?
I do know why this caused an issue though. This is interpreted as a function without a return type. This causes the return type to be dynamic, essentially disabling dart's typesystem. That is why the compiler doesn't complain. Then this function returns null and throws this error.
Another thing, RaisedButton is depricated. Please don't use it. Use ElevatedButton instead.
I am using the following package https://pub.dev/packages/get. Do I need to close my .obs in the onClose of a GetxController? I can't find anything about this in the docs. And looking at my memory it appears that the are being destroyed automatically.
In my understanding of GetX + Flutter so far...
No, you shouldn't have to remove .obs in the close() method of GetxControllers. Disposal of observables from a Controller are done automatically when the Controller is removed from memory.
GetX disposes/removes GetxControllers (and their observables) when the widget in which they are contained are popped off the widget stack / removed from the widget tree (by default, but can be overridden).
You can see this in the override of dispose() methods of various Get widgets.
Here's a snippet of dispose() that's run when GetX widgets are popped/removed:
#override
void dispose() {
if (widget.dispose != null) widget.dispose(this);
if (isCreator || widget.assignId) {
if (widget.autoRemove && GetInstance().isRegistered<T>(tag: widget.tag)) {
GetInstance().delete<T>(tag: widget.tag);
}
}
subs.cancel();
_observer.close();
controller = null;
isCreator = null;
super.dispose();
}
When you use Bindings or Get.to() you're using GetPageRoute's which do cleanup by Route names:
#override
void dispose() {
if (Get.smartManagement != SmartManagement.onlyBuilder) {
WidgetsBinding.instance.addPostFrameCallback((_) => GetInstance()
.removeDependencyByRoute("${settings?.name ?? routeName}"));
}
super.dispose();
}
Test App
Below is a test App you can copy/paste into Android Studio / VSCode and run to watch the debug or run window output for GETX lifecycle events.
GetX will log the creation & disposal of Controllers in and out of memory.
The app has a HomePage and 3 ChildPages using Get Controllers in 3 ways, all which remove itself from memory:
GetX / GetBuilder
Get.put
Bindings
import 'package:flutter/material.dart';
import 'package:get/get.dart';
void main() {
// MyCounterBinding().dependencies(); // usually where Bindings happen
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return GetMaterialApp(
title: 'GetX Dispose Ex',
home: HomePage(),
);
}
}
class HomePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('GetX Dispose Test'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
RaisedButton(
child: Text('GetX/Builder Child'),
onPressed: () => Get.to(ChildPage()),
),
RaisedButton(
child: Text('Get.put Child'),
onPressed: () => Get.to(ChildPutPage()),
),
RaisedButton(
child: Text('Binding Child'),
onPressed: () => Get.to(ChildBindPage()),
),
],
),
),
);
}
}
/// GETX / GETBUILDER
/// Creates Controller within the Get widgets
class ChildPage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('GetX Dispose Test Counter'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Text('This is the Child Page'),
GetX<ChildX>(
init: ChildX(),
builder: (cx) => Text('Counter: ${cx.counter}', style: TextStyle(fontSize: 20),),
),
GetBuilder<ChildX>(
init: ChildX(),
builder: (cx) => RaisedButton(
child: Text('Increment'),
onPressed: cx.inc,
),
),
],
),
),
);
}
}
/// GET.PUT
/// Creates Controller instance upon Build, usable anywhere within the widget build context
class ChildPutPage extends StatelessWidget {
//final ChildX cx = Get.put(ChildX()); // wrong place to put
// see https://github.com/jonataslaw/getx/issues/818#issuecomment-733652172
#override
Widget build(BuildContext context) {
final ChildX cx = Get.put(ChildX());
return Scaffold(
appBar: AppBar(
title: Text('GetX Dispose Test Counter'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Text('This is the Child Page'),
Obx(
() => Text('Counter: ${cx.counter}', style: TextStyle(fontSize: 20),),
),
RaisedButton(
child: Text('Increment'),
onPressed: cx.inc,
)
],
),
),
);
}
}
class MyCounterBinding extends Bindings {
#override
void dependencies() {
Get.lazyPut(() => ChildX(), fenix: true);
}
}
/// GET BINDINGS
/// Normally the MyCounterBinding().dependencies() call is done in main(),
/// making it available throughout the entire app.
/// A lazyPut Controller /w [fenix:true] will be created/removed/recreated as needed or
/// as specified by SmartManagement settings.
/// But to keep the Bindings from polluting the other examples, it's done within this
/// widget's build context (you wouldn't normally do this.)
class ChildBindPage extends StatelessWidget {
#override
Widget build(BuildContext context) {
MyCounterBinding().dependencies(); // just for illustration/example
return Scaffold(
appBar: AppBar(
title: Text('GetX Dispose Test Counter'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Text('This is the Child Page'),
Obx(
() => Text('Counter: ${ChildX.i.counter}', style: TextStyle(fontSize: 20),),
),
RaisedButton(
child: Text('Increment'),
onPressed: ChildX.i.inc,
)
],
),
),
);
}
}
class ChildX extends GetxController {
static ChildX get i => Get.find();
RxInt counter = 0.obs;
void inc() => counter.value++;
}
Notes
Get.to vs. Navigator.push
When using Get.put() in a child widget be sure you're using Get.to() to navigate to that child rather than Flutter's built-in Navigator.push.
GetX wraps the destination widget in a GetPageRoute when using Get.to. This Route class will dispose of Controllers in this route when navigating away / popping the widget off the stack. If you use Navigator.push, GetX isn't involved and you won't get this automatic cleanup.
Navigator.push
onPressed: () => Navigator.push(context, MaterialPageRoute(
builder: (context) => ChildPutPage())),
Get.to
onPressed: () => Get.to(ChildPutPage()),
Based from the code of the super implementation of onClose, by default it does nothing currently.
https://github.com/jonataslaw/getx/blob/7146b6a53c0648104e4f623385deaff055e0036a/lib/get_instance/src/lifecycle.dart#L56
And from the comments, it says:
/// Called before [onDelete] method. [onClose] might be used to
/// dispose resources used by the controller. Like closing events,
/// or streams before the controller is destroyed.
/// Or dispose objects that can potentially create some memory leaks,
/// like TextEditingControllers, AnimationControllers.
/// Might be useful as well to persist some data on disk.
void onClose() {}
from that I think you need to manually close your streams in YourController::onClose() override function.
It appears you can use obs safely when using GetWorkers. Run this code and you'll notice that when you click the buttons a few time there will only be one print per page switch.
void main(){
runApp(GetMaterialApp(home: TestWidget(),));
}
class TestWidget extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Center(
child: RaisedButton(
child: Text('next'),
onPressed: () => Get.to<SomeWidget>(SomeWidget()),
),
);
}
}
class SomeWidget extends StatelessWidget {
RxBool isSubscribed = false.obs;
SomeWidget() {
ever(isSubscribed, (_) => print('test'));
}
#override
Widget build(BuildContext context) {
return Center(
child: RaisedButton(
child: Text('back'),
onPressed: () {
isSubscribed.value = !isSubscribed.value;
Get.back();
},
),
);
}
}
I am very new to Flutter but coming from an Angular background here. Say I want to build a BaseFrame for my app, and depending on the routing, I want to change the INSIDE of that BaseFrame. I don't understand how this would work?
In Angular it would be something like:
'/page-one': PageOne(),
'/page-two': PageTwo(), children: [
'/part-1': Part1(),
'/part-2': Part2(),
];
And in this case, if you navigate to /page-two/part-1 then it would load PageTwo(), and it would load Part1() wherever you specified <app-route></app-route> on PageTwo(). I don't understand how one would do this in Flutter because in Flutter it seems like you can only ever have a single flat route in your main.dart (in your MaterialApp builder)
The best thing I can think of is to have a variable on PageTwo(), and have a type of switch statement:
switch (subPage) {
case '/part-1':
return Part1();
case '/part-2':
return Part2();
}
But this seems like a crappy solution. You also now have the problem of fixing animations etc yourself (because the MaterialApp won't help you here automatically).
Here is something about this but this seems super complicated for a noob. Is this really the right/only way to do this:
Nesting routes with flutter
You can do something like that using this package qlevar_router
A full example of your case
import 'package:flutter/material.dart';
import 'package:qlevar_router/qlevar_router.dart';
void main() {
runApp(MyApp());
}
class AppRoutes {
final routes = <QRouteBase>[
QRoute(
path: '/page-one',
page: (c) => PageOne(),
),
QRoute(
path: '/page-two',
page: (c) => PageTwo(c),
initRoute: '/part-1',
children: [
QRoute(
path: '/part-1',
page: (c) => Part1(),
),
QRoute(
path: '/part-2',
page: (c) => Part2(),
)
])
];
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp.router(
routerDelegate: QR.router(AppRoutes().routes, initRoute: '/page-one'),
routeInformationParser: QR.routeParser(),
);
}
}
class PageOne extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(children: [
Text('This is page one'),
TextButton(
onPressed: () => QR.to('/page-two/part-1'),
child: Text('To Part 1')),
TextButton(
onPressed: () => QR.to('/page-two/part-2'),
child: Text('To Part 2')),
]),
),
);
}
}
class PageTwo extends StatelessWidget {
final QRouteChild child;
PageTwo(this.child);
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(children: [
Text('This is page one'),
TextButton(onPressed: () => QR.back(), child: Text('Back')),
TextButton(
onPressed: () => QR.to('/page-two/part-1'),
child: Text('To Part 1')),
TextButton(
onPressed: () => QR.to('/page-two/part-2'),
child: Text('To Part 2')),
SizedBox(
width: 500,
height: 500,
child: child.childRouter,
)
]),
),
);
}
}
class Part1 extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Center(child: Text('This is part 1'));
}
}
class Part2 extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Center(child: Text('This is part 2'));
}
}
Note that page-tow doesn't change at all when you navigate between the children part-1 and part-2
You could just use something like a TabBar/TabBarView to have other pages show up within the pages you're on. Which then you could give an integer as a parameter of your PageTwo class which you could use that integer to select which page you initially navigate to. This is a fairly straightforward way to do what I think you want but more limited since you won't have different navigators within each of those initial pages. Unless the Parts pages are meant to have their own navigation. If you want to have separate navigators for screens you can do this. That's how the CupertinoTabbedScaffold works (though with CupertinoApps). Which may be something to look into.
i'm brand new to Flutter.
I'm trying to open a panel pressing a button and than closing it by pressing a button on that panel.
I've managed to do it by writing the code in the same page.
What i can't do is splitting the code and keep everything working.
What I'm actually doing is calling a variable in the State of a widget that is initialized False and then with an if statement i'm calling: or an empty container or the panel i want.
When i press the button i call SetState(){} and the variable changes to true to let the panel appears, then in the panel there's button that do opposite thing.
Assuming that what i'm doing it is correct. How to i keep doing this with the panel refactored in a new page?
I've red something about streams and inherited widgets but i haven't completely understood
If I understand correctly, you want to notify a StatefullWidget from another StatefullWidget. There are several approaches on this one but since you've mentioned Streams, I'll try to post an example and explain a bit this scenario.
So basically, you can consider the streams like a pipe linked to a faucet in one end and the other end it's added into a cup (the end can be split in multiple ends and put in multiple cups, "broadcast streams").
Now, the cup is the listener (subscriber) and waits for water to drop trough the pipe.
The faucet is the emitter, and it will emit water droplets when the faucet is opened.
The faucet can be opened when the other end is put into a cup, this is a smart faucet with some cool sensors, (the emitter will start emitting events when a subscriber is "detected).
The droplets are actual events that are happening in the the app.
Also you must remember to close the faucet in order to avoid a massive leak from your cup into the kitchen floor. (you must cancel the subscribers when you've done handling events to avoid a leak).
Now for your particular case here's the code snippet that kind of illustrate the above metaphor:
class ThePannel extends StatefulWidget { // this is the cup
final Stream<bool> closeMeStream; // this is the pipe
const ThePannel({Key key, this.closeMeStream}) : super(key: key);
#override
_ThePannelState createState() => _ThePannelState(closeMeStream);
}
class _ThePannelState extends State<ThePannel> {
bool _closeMe = false;
final Stream<bool> closeMeStream;
StreamSubscription _streamSubscription;
_ThePannelState(this.closeMeStream);
#override
void initState() {
super.initState();
_streamSubscription = closeMeStream.listen((shouldClose) { // here we listen for new events coming down the pipe
setState(() {
_closeMe = shouldClose; // we got a new "droplet"
});
});
}
#override
void dispose() {
_streamSubscription.cancel(); // THIS IS QUITE IMPORTANT, we have to close the faucet
super.dispose();
}
#override
Widget build(BuildContext context) {
return Stack(
children: <Widget>[
SomeWidgetHere(shouldClose: _closeMe),
RaisedButton(
onPressed: () {
setState(() {
_closeMe = true;
});
},
)
],
);
}
}
class SomeWidgetThatUseThePreviousOne extends StatefulWidget { // this one is the faucet, it will emit droplets
#override
_SomeWidgetThatUseThePreviousOneState createState() =>
_SomeWidgetThatUseThePreviousOneState();
}
class _SomeWidgetThatUseThePreviousOneState
extends State<SomeWidgetThatUseThePreviousOne> {
final StreamController<bool> thisStreamWillEmitEvents = StreamController(); // this is the end of the pipe linked to the faucet
#override
Widget build(BuildContext context) {
return Stack(
children: <Widget>[
ThePannel(closeMeStream: thisStreamWillEmitEvents.stream), // we send the other end of the pipe to the cup
RaisedButton(
child: Text("THIS SHOULD CLOSE THE PANNEL"),
onPressed: () {
thisStreamWillEmitEvents.add(true); // we will emit one droplet here
},
),
RaisedButton(
child: Text("THIS SHOULD OPEN THE PANNEL"),
onPressed: () {
thisStreamWillEmitEvents.add(false); // we will emit another droplet here
},
)
],
);
}
#override
void dispose() {
thisStreamWillEmitEvents.close(); // close the faucet from this end.
super.dispose();
}
}
I hope that my analogy will help you understand a bit the streams concept.
If you want to open an dialog (instead of what you call a "panel") you can simply give the selected data back when you close the dialog again.
You can find a good tutorial here: https://medium.com/#nils.backe/flutter-alert-dialogs-9b0bb9b01d28
you can navigate and return data from another screen like that :
import 'package:flutter/material.dart';
void main() {
runApp(MaterialApp(
title: 'Returning Data',
home: HomeScreen(),
));
}
class HomeScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Returning Data Demo'),
),
body: Center(child: SelectionButton()),
);
}
}
class SelectionButton extends StatelessWidget {
#override
Widget build(BuildContext context) {
return RaisedButton(
onPressed: () {
_navigateAndDisplaySelection(context);
},
child: Text('Pick an option, any option!'),
);
}
// A method that launches the SelectionScreen and awaits the result from
// Navigator.pop!
_navigateAndDisplaySelection(BuildContext context) async {
// Navigator.push returns a Future that will complete after we call
// Navigator.pop on the Selection Screen!
final result = await Navigator.push(
context,
MaterialPageRoute(builder: (context) => SelectionScreen()),
);
// After the Selection Screen returns a result, hide any previous snackbars
// and show the new result!
Scaffold.of(context)
..removeCurrentSnackBar()
..showSnackBar(SnackBar(content: Text("$result")));
}
}
class SelectionScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Pick an option'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: RaisedButton(
onPressed: () {
// Close the screen and return "Yep!" as the result
Navigator.pop(context, 'Yep!');
},
child: Text('Yep!'),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: RaisedButton(
onPressed: () {
// Close the screen and return "Nope!" as the result
Navigator.pop(context, 'Nope.');
},
child: Text('Nope.'),
),
)
],
),
),
);
}
}
for more details about navigation:
https://flutter.dev/docs/cookbook/navigation/returning-data
I am learning app development on Flutter and can't get my Slider to work within the AlertDialog. It won't change it's value.
I did search the problem and came across this post on StackOverFlow:
Flutter - Why slider doesn't update in AlertDialog?
I read it and have kind of understood it. The accepted answer says that:
The problem is, dialogs are not built inside build method. They are on a different widget tree. So when the dialog creator updates, the dialog won't.
However I am not able to understand how exactly does it have to be implemented as not enough background code is provided.
This is what my current implementation looks like:
double _fontSize = 1.0;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(qt.title),
actions: <Widget>[
IconButton(
icon: Icon(Icons.format_size),
onPressed: () {
getFontSize(context);
},
),
],
),
body: ListView.builder(
padding: EdgeInsets.symmetric(vertical: 15.0),
itemCount: 3,
itemBuilder: (context, index) {
if (index == 0) {
return _getListTile(qt.scripture, qt.reading);
} else if (index == 1) {
return _getListTile('Reflection:', qt.reflection);
} else {
return _getListTile('Prayer:', qt.prayer);
}
})
);
}
void getFontSize(BuildContext context) {
showDialog(context: context,builder: (context){
return AlertDialog(
title: Text("Font Size"),
content: Slider(
value: _fontSize,
min: 0,
max: 100,
divisions: 5,
onChanged: (value){
setState(() {
_fontSize = value;
});
},
),
actions: <Widget>[
RaisedButton(
child: Text("Done"),
onPressed: (){},
)
],
);
});
}
Widget parseLargeText(String text) {...}
Widget _getListTile(String title, String subtitle) {...}
I understand that I will need to make use of async and await and Future. But I am not able to understand how exactly. I've spent more than an hour on this problem and can't any more. Please forgive me if this question is stupid and noobish. But trust me, I tried my best.
Here is a minimal runnable example. Key points:
The dialog is a stateful widget that stores the current value in its State. This is important because dialogs are technically separate "pages" on your app, inserted higher up in the hierarchy
Navigator.pop(...) to close the dialog and return the result
Usage of async/await
import 'package:flutter/material.dart';
void main() => runApp(App());
class App extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: HomePage(),
);
}
}
class HomePage extends StatefulWidget {
#override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
double _fontSize = 20.0;
void _showFontSizePickerDialog() async {
// <-- note the async keyword here
// this will contain the result from Navigator.pop(context, result)
final selectedFontSize = await showDialog<double>(
context: context,
builder: (context) => FontSizePickerDialog(initialFontSize: _fontSize),
);
// execution of this code continues when the dialog was closed (popped)
// note that the result can also be null, so check it
// (back button or pressed outside of the dialog)
if (selectedFontSize != null) {
setState(() {
_fontSize = selectedFontSize;
});
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text('Font Size: ${_fontSize}'),
RaisedButton(
onPressed: _showFontSizePickerDialog,
child: Text('Select Font Size'),
)
],
),
),
);
}
}
// move the dialog into it's own stateful widget.
// It's completely independent from your page
// this is good practice
class FontSizePickerDialog extends StatefulWidget {
/// initial selection for the slider
final double initialFontSize;
const FontSizePickerDialog({Key key, this.initialFontSize}) : super(key: key);
#override
_FontSizePickerDialogState createState() => _FontSizePickerDialogState();
}
class _FontSizePickerDialogState extends State<FontSizePickerDialog> {
/// current selection of the slider
double _fontSize;
#override
void initState() {
super.initState();
_fontSize = widget.initialFontSize;
}
#override
Widget build(BuildContext context) {
return AlertDialog(
title: Text('Font Size'),
content: Container(
child: Slider(
value: _fontSize,
min: 10,
max: 100,
divisions: 9,
onChanged: (value) {
setState(() {
_fontSize = value;
});
},
),
),
actions: <Widget>[
FlatButton(
onPressed: () {
// Use the second argument of Navigator.pop(...) to pass
// back a result to the page that opened the dialog
Navigator.pop(context, _fontSize);
},
child: Text('DONE'),
)
],
);
}
}
You just need to warp the AlertDialog() with a StatefulBuilder()