Flutter hot reloading with VSCode sometimes works, sometimes doesn't - flutter

The title says it all. Here's a gif demonstrating. Some changes to code the UI gets updated as expected whereas at other times the updates aren't reflected.
This prompt in VSCode does not mean that the app has hot reloaded.
Syncing files to device Android SDK built for x86."
Heres my main.dart file that has the two lists I want to flip for reference.
class _MyHomePageState extends State<MyHomePage> {
// List<Color> colors = [Colors.yellow, Colors.red, Colors.yellow];
List<Color> colors = [Colors.red, Colors.white, Colors.blue];
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: colors
.map((element) => Expanded(
child: Container(
decoration: BoxDecoration(color: element),
// decoration: BoxDecoration(color: _counter.isEven ? Colors.red : Colors.blue),
)))
.toList()),
),
}
}
Please advise me on how to get the VScode hot reloading to work when I do command+s.
When I move colors out of the state of the _MyHomePageStatte Widget, the behavior is the same. Here's the gif demo

If you update a member variable in a stateful widget, you must hot restart the app or close and reopen the widget
And to make the hot reload working with the variable outside of the widget, you must use const varName instead of final varName or <Type> varName. If the variable cannot be converted to const then you have no option than hot restart the app

it's because first color changed is a variable, when you save hot reload apply the new color, but when you change the second variable, it's a variable in your state, hot reload change your variables but the state of your widget dosn't change, it 's not a probleme it's normal. If you want to see your change you can reload your application.

Only the Variables which are inside build or updated inside build are impacted through hot reload,
If you want to change variable outside build or reload the state you must consider hot restart.

Related

A small part of the UI is not getting re rendered on state change

I have a text widget in the cellBuilder of SF Datepicker in my app whose color should conditionally render on the basis of a state of a variable. When I change the state, the widget is getting re-rendered(the latest value of the state of the variable is printed and another text widget outside of cellBuilder which conditionally renders on the basis of the state also works fine). But the color of the text doesn't change.
This is the build method of the main widget:
#override
Widget build(BuildContext context) {
return Column(
children: [
unfinishedWeeks.length > 0
? Text("Unfinished weeks")
: Container(), //This text is visible when the state of unfinishedWeeks changes
Container(
height: 320,
child: SfDateRangePicker(
controller: _controller,
cellBuilder:
(BuildContext context, DateRangePickerCellDetails details) {
debugPrint(unfinishedWeeks
.toString()); //the current state of unfinishedWeeks is printed
return Text(
details.date.day.toString(),
style: TextStyle(
color: unfinishedWeeks.length >
0 //this value doesn't change when the state of unfinishedWeeks changes
? Color.fromARGB(255, 170, 0, 0)
: Color.fromARGB(255, 47, 15, 83),
),
);
},
),
),
],
);
}
Where am I going wrong? Does it have to do with SF Datepicker?
SfDateRangePicker rebuild UI only when the onSelectionChanged function is called
Can you try calling setState on the section where unfinishedWeeks is being updated.
I figured out a way: using Keys to force the UI to re-render. So I created a new widget enclosing the text widget and provided this widget with a key.

Flutter photo_view package gestures not working properly

Hi I am a flutter mobile developer and I tried to use this package: https://pub.dev/packages/photo_view/versions for an offline map. I tried zoom and drag and other gestures. It seems working properly for zooming most of the time, but when I tried to drag the picture It has a less than 10 percent success to move it. Here is my code, can somebody help me what coul'd I do wrong? In the package example It seems like It's working properly.
class OfflineMapWidget extends StatefulWidget {
final Session session;
final bool connectedToNetwork;
const OfflineMapWidget(
{Key? key, required this.session, required this.connectedToNetwork})
: super(key: key);
#override
_OfflineMapWidgetState createState() => _OfflineMapWidgetState();
}
class _OfflineMapWidgetState extends State<OfflineMapWidget> {
#override
Widget build(BuildContext context) {
return Container(
color: Colors.black,
child: SafeArea(
child: Theme(
data: ThemeData(
brightness: Brightness.dark,
appBarTheme: AppBarTheme(
backgroundColor: Color.fromARGB(255, 65, 116, 131))),
child: Scaffold(
appBar: AppBar(
leading: MenuWidget(),
actions: [widget.connectedToNetwork ? QrPaymentButton(session: widget.session) : Container()],
),
body: Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
color: Colors.white,
child: PhotoView(
imageProvider: AssetImage('assets/images/offline_map.png'),
),
),
),
),
),
);
}
}
Update: I found the problem. This Widget was in a ZoomDrawer (another pub dev package), and that Widget confused this one, so I need to find another solution. If somebody else uses this 2 package in one the problem is here. The solution is simple, you can disable drag in ZoomDrawer with the disableDragGesture property. If you don't want to disable it on all menu points you can check if you are in the mentioned menu point and disable only when this one is up.I write this one down in the comments as well so it will be more clear.
I found the problem. This Widget was in a ZoomDrawer (another pub dev package), and that Widget confused this one, so I need to find another solution. If somebody else uses this 2 package in one the problem is here. The solution is simple, you can disable drag in ZoomDrawer with the disableDragGesture property. If you don't want to disable it on all menu points you can check if you are in the mentioned menu point and disable only when this one is up.

Flutter app variables reset each time you leave the page

I'm making a flutter app. Each time I leave the page, the variables reset. How do I make it so that the data stays the same, even if you leave the page? I'm using getx for state management. Here is my code:
//Button that leaves the page
Align(
alignment: Alignment.topLeft,
child: IconButton(
onPressed: () => Get.back(),
icon: const Icon(Icons.arrow_back),
),
),
When you click the button, it leaves the page and resets the variable maintasks shown here.
Align(
alignment: Alignment.topLeft,
child: Padding(
padding: const EdgeInsets.only(left: 25.0),
child: Text(
maintasks,
style: const TextStyle(
fontSize: 23,
color: Colors.black,
fontWeight: FontWeight.w800,
),
),
),
),
There is a function which changes the variable maintasks to the user input. However this user input is reset each time you leave the page. I've tried using SetState to save the variable but for some reason it doesn't work.
Sorry if my question is worded badly. If anyone knows how to do this, please tell me. Thanks in advance.
Widget state is reset as soon as the widget is disposed.
For this, using GetX, you could use GetXControllers
Example, let's imagine you need a state that's composed by a username and a password,
class LoginController extends GetxController {//GetxController comes from Getx package
var username = ''.obs;//creates a stream that can be listened from the UI, whose value is a String
var password = ''.obs;//same here
void onUsernameChanged(String newValue) {
username(newValue);//changes username stream last value to newValue's
}
void onPasswordChanged(String newValue) {
password(newValue);//the same
}
}
Now, you must insert an instance of this controller in your widget tree before the widget is built (For example, in initState)
#override
void initState() {
_controller = Get.put<LoginController>(LoginController());
super.initState();
}
Once you know you have this instance in the widget tree, you just listen to its streams using GetX widget
GetX<LoginController>(
builder: (controller)=>Text(controller.username.value)
)//this guy will repaint every time username changes
This is important because the instance of this widget will remain alive in the widget tree until either the app ends or the controller is explicitly deleted

Set default icon theme to cupertino flutter appbar

The app that im building requires me to have an AppBar with a leading back button. However I prefer the cupertino back button(iOS-style) for the leading icon instead of the default back button for android. I am aware that I can manually change the leading button of each AppBar by using an iconButton but i was wondering if there is any easy way to do this like a theme. Any help appreciated.
Instead of using MaterialApp as your root widget you can use CupertinoApp to do the same, assuming that the above changing of the AppBar is needed for each screen in your app. This will automatically set the icon as you require
Here is a simple example to help you
Root Widget or starting point of the app
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
static const String _title = 'Flutter Code Sample';
#override
Widget build(BuildContext context) {
return const CupertinoApp(
title: _title,
home: MyStatefulWidget(),
);
}
}
Then using a CupertinoPageScaffold where you want the CupertinoNavigationBar (I mean your appbar with ios icons) with the chevron icon like ios
Widget build(BuildContext context) {
return CupertinoPageScaffold(
navigationBar: CupertinoNavigationBar(
// Try removing opacity to observe the lack of a blur effect and of sliding content.
automaticallyImplyLeading: true // This will decide if the leading icon comes in by default
backgroundColor: CupertinoColors.systemGrey.withOpacity(0.5),
middle: const Text('Sample Code'),
),
child: Column(
children: <Widget>[
Container(height: 50, color: CupertinoColors.systemRed),
Container(height: 50, color: CupertinoColors.systemGreen),
Container(height: 50, color: CupertinoColors.systemBlue),
Container(height: 50, color: CupertinoColors.systemYellow),
],
),
);
Facing a relatively similar problem I used the builder property, which it should work with any App like :
CupertinoApp(
builder: (_, child) => IconTheme(
data: IconThemeData(
size: 15,
color: const Color(0xffffffff),
),
child: child,
),
)
My problem was with the default icon color and size but you can use AppBarTheme or any similar widget to achieve what you want.
This may help you override default value with majority of the lacking theme delegates when working with the cupertino family (It's not yet mature like the material but I can see the constant and rapid effort and the future of it).

Page recreate when keyboard is open on showDialog

I have a problem with my flutter project, I create button to display dialog with form and textfield, when dialog is open then I tap texfield, page is recreate, this is my code
void _showDialog(){
showDialog(
context: context,
builder: (BuildContext context) {
return CupertinoAlertDialog(
title: Text('Add New'),
content: Card(
color: Colors.transparent,
elevation: 0.0,
child: Column(
children: <Widget>[
TextField(
decoration: InputDecoration(
labelText: "Item",
filled: true,
fillColor: Colors.grey.shade50),
),
],
),
),
);
},
);
}
how I can solve it? thank you so much for your help
Mmm, from your code nothing looks weird... maybe you should share the entire class, or your business logic from another part of the tree (like a stream that rebuilds your view )...
I did a basic test in the Simulator and works fine.
But now I figure you are using a StatefulWidget, cause you have access to the context, so many some other code is doing setState().
Opening or closing the keyboard by pressing on a TextField rebuilds the Scaffold or whichever material is used to wrap your screen. This is normal behavior.
By 'recreating the page' do you mean that it loses its state? (it loses the values for data like if you use hot-restart instead of hot-reload), if so then this is not the standard behavior and we may need more information on your page/code to figure this out.