I am developing a library that has a run
function that runs an entire app boilerplate with lots of configuration parameters such as LoginPageColor
How to perform hot reload in way to update the app when I change the color ?
This does not work.
void main() {
run(loginPageColor: Colors.red); // change this
}
void run({required Color loginPageColor}) {
runApp(MyApp(loginPageColor: loginPageColor));
}
class MyApp extends StatelessWidget {
final Color loginPageColor;
const MyApp({Key? key, required this.loginPageColor}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
home: LoginPage(color: loginPageColor),
);
}
}
class LoginPage extends StatelessWidget {
final Color color;
const LoginPage({Key? key, required this.color}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: color,
body: Center(
child: Text('Login Page'),
),
);
}
}
I read somewhere hot reload works with isolate, so I made the configuration top-level function which is an UGLY SOLUTION but it works. Is there a more elegant way to make hot reload works without using this top-level
and getter approach ?
MaterialColor getColor (){
return Colors.pink; // change this to Red
}
void main() {
run(loginPageColor: getColor);
}
void run({required Color Function() loginPageColor}) {
runApp(MyApp(loginPageColor: loginPageColor));
}
class MyApp extends StatelessWidget {
final Color Function() loginPageColor;
const MyApp({Key? key, required this.loginPageColor}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
home: LoginPage(color: loginPageColor()),
);
}
}
class LoginPage extends StatelessWidget {
final Color color;
const LoginPage({Key? key, required this.color}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: color,
body: Center(
child: Text('Login Page'),
),
);
}
}
NOTE: It is ugly because I don’t want to write a disclaimer in the package description that the configuration should be a "TOP-LEVEL" function otherwise it won’t work with hot reload. Unless this is a Dart limitation, but I don’t believe so because Flutter Widgets
are not top level but they work with hot reload.
Is there a good official source that explains deeply how the hot reload works in Dart ?. Most source just explains how to use it with widget but I couldn’t find a source that explains how to use it beyond that.
2
Answers
Flutter uses DVM for rendering a widgets and it works like a below:
1:State Preservation:
Hot reload preserves the app’s current state. When you make changes to the code, the app continues running, and the state (like user input, scroll position, etc.) is retained.
Source Code Changes:
When you save your changes, Flutter detects the modified files. It compiles only those files rather than the entire application.
Incremental Compilation:
Flutter uses the Dart VM to perform an incremental compilation of the modified code. This means it only re-compiles the parts of the code that have changed.
Widget Tree Update: Flutter’s engine sends the updated code to the Dart VM, which updates the widget tree. The framework rebuilds the affected widgets with the new code.
Rebuilding Widgets:The updated widget tree is then rendered on the screen. Since the app state is preserved, the UI reflects the changes instantly without losing the context.
In basic terms , if you do hot reload , the build() is getting re-build, preserving the previous paths and states . Please note , the initState() will not reset , you need to run to do so or navigate back to this page.