I have encountered a weird problem in Flutter. In my app, I'm showing a splash screen before my models and other things are initialized, then I show a different Widget for the duration of the application.
Things work as expected - unless the first Widget contains anything that animates (CircularProgressIndicator
for example)! In that case, the build
method is never called again when I call setState
- even if I call setState
several seconds later from a Timer
.
If I hit "Hot Restart" or "Hot Reload" in the IDE, the app is rebuilt as expected. It also works if the first Widget doesn't contain a CircularProgressIndicator
, or any other animated widget.
Minimal example:
import 'dart:async';
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
MyApp({Key key}) : super(key: key);
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
bool splash = true;
@override
void initState() {
super.initState();
Timer(Duration(milliseconds: 3000), (){
if( mounted ) setState((){
print('Enough splashing!');
splash = false;
});
});
}
@override
Widget build(BuildContext context) {
print('build splash: $splash');
return MaterialApp(
title: 'FlutterTest',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: Scaffold(
appBar: AppBar(
title: Text('FlutterTest'),
),
body: Center(
child: splash
? Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
CircularProgressIndicator(strokeWidth: 1, valueColor: AlwaysStoppedAnimation<Color>(Colors.red)),
Text('Splash...', style: TextStyle(color: Colors.red))
],
)
: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('FlutterTest', style: TextStyle(color: Colors.blue)),
],
),
),
)
);
}
}
Result with CircularProgressIndicator
present:
I/flutter (19306): build splash: true
I/flutter (19306): Enough splashing!
Result without CircularProgressIndicator
, or after "Hot Reload"/"Hot Refresh":
I/flutter (19436): build splash: true
I/flutter (19436): Enough splashing!
I/flutter (19436): build splash: false
What is going on here?
I'm seeing this on an Android emulator in debug mode.
flutter doctor -v
[✓] Flutter (Channel stable, 1.20.3, on Mac OS X 10.15.1 19B88, locale en-SE)
• Flutter version 1.20.3 at /Users/username/dev/flutter
• Framework revision 216dee60c0 (5 weeks ago), 2020-09-01 12:24:47 -0700
• Engine revision d1bc06f032
• Dart version 2.9.2
[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.2)
• Android SDK at /Users/username/Library/Android/sdk
• Platform android-30, build-tools 30.0.2
• Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
• Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1136-b06)
• All Android licenses accepted.
[✓] Xcode - develop for iOS and macOS (Xcode 11.1)
• Xcode at /Applications/Xcode.app/Contents/Developer
• Xcode 11.1, Build version 11A1027
• CocoaPods version 1.8.4
[!] Android Studio (version 3.2)
• Android Studio at /Applications/Android Studio.app/Contents
✗ Flutter plugin not installed; this adds Flutter specific functionality.
✗ Dart plugin not installed; this adds Dart specific functionality.
• Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1136-b06)
[✓] IntelliJ IDEA Community Edition (version 2018.3)
• IntelliJ at /Applications/IntelliJ IDEA CE.app
• Flutter plugin version 32.0.2
• Dart plugin version 183.4733
[✓] Connected device (1 available)
• sdk gphone x86 (mobile) • emulator-5554 • android-x86 • Android 11 (API 30) (emulator)
UPDATE
Tried it on another computer, and it worked. That computer had Flutter version 1.12.13+hotfix.8, so I tried updating Flutter to 1.22 on the computer where it didn't work. Still the same result. I checked the emulators - they were running the exact same API, system image, emulator version, and same HAXM version on both computers.
On the failing computer, I tried with a lower Android API - it worked. So I tried updating the system image revision for API 30 - still the same problem with a new AVD. As a last resort, I updated the emulator and HAXM to the latest revisions. Now it worked on API 30. So it seems the problem was somewhere in the emulator/HAXM, even though the exact same versions worked on another computer.