I am using flutter with dio package to download files like powerpoint and videos ...etc
what i want to ask is how to download large file in background
try {
await dio.download(
fileURL, '$dir/$fileName.pptx',
onReceiveProgress: showDownloadProgress,
deleteOnError: true);
print("BBBB");
openDownloadedFile = '$dir/$fileName.pptx';
print("CCCC");
} on DioError catch(e) {
print("11");
final file = File('$dir/$fileName.pptx');
file.deleteSync(recursive: true);
if(e.response != null) {
print("22");
print(e.response.data);
print(e.response.headers);
print(e.response.request);
} else{
// Something happened in setting up or sending the request that triggered an Error
print(e.request);
print(e.message);
}
}
Best Regard
Since this question has been asked, there is official support in Flutter for Background Tasks. You may want to check that out now.
Docs Link: https://docs.flutter.dev/development/packages-and-plugins/background-processes
Example Link: https://flutteragency.com/schedule-background-tasks/
Complete Example (from the docs)
import 'package:flutter/material.dart';
import 'package:web_socket_channel/web_socket_channel.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
#override
Widget build(BuildContext context) {
const title = 'WebSocket Demo';
return const MaterialApp(
title: title,
home: MyHomePage(
title: title,
),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({
super.key,
required this.title,
});
final String title;
#override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final TextEditingController _controller = TextEditingController();
final _channel = WebSocketChannel.connect(
Uri.parse('wss://echo.websocket.events'),
);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Form(
child: TextFormField(
controller: _controller,
decoration: const InputDecoration(labelText: 'Send a message'),
),
),
const SizedBox(height: 24),
StreamBuilder(
stream: _channel.stream,
builder: (context, snapshot) {
return Text(snapshot.hasData ? '${snapshot.data}' : '');
},
)
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _sendMessage,
tooltip: 'Send message',
child: const Icon(Icons.send),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
void _sendMessage() {
if (_controller.text.isNotEmpty) {
_channel.sink.add(_controller.text);
}
}
#override
void dispose() {
_channel.sink.close();
_controller.dispose();
super.dispose();
}
}
I would suggest that you use the Flutter Downloader plugin to download large files as it uses the native download manager. Dio is more suited for downloading small files while the app is open.
Related
In my Home page I am fetching data from Firestore database and showing them using a ListView.builder. More specifically, I am showing all the subjects that belongs to the current user. In home page there is a button which takes us the FirstPage where users can create new subject. When user create a subject, that subject is added to the database. But when user go back to the Home page, data shown there should be updated, i,e. the list of subjects shown there should contain the newly created subject.
I am using streamController to call setState in Home page after the new subject is added to database but it is not working i,e. when user go back to home page it shows the previous data only. All other things are working (i,e. data is successfully added to data base. When I again reload the home page it shows updated data)
Can someone look into it and tell me what's wrong with my approach ? Or if it is possible with the provider package, then can you please give me an example of that in similar situation.
Here is my code,
// Stream controller
StreamController<bool> streamControllerHome = StreamController<bool>();
Future main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
runApp(MyApp());
}
class MyApp extends StatefulWidget {
MyApp({Key? key}) : super(key: key);
#override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.deepPurple
),
home: Home(stream: streamControllerHome.stream),
);
}
}
// Code for Home page
class Home extends StatefulWidget {
final Stream<bool> stream;
const Home({Key? key, required this.stream}) : super(key: key);
#override
State<Home> createState() => _HomeState();
}
class _HomeState extends State<Home> {
setStateHome(bool check) {
if (check) {
setState(() {
});
}
}
#override
void initState() {
// TODO: implement initState
super.initState();
if (!streamControllerHome.hasListener) {
widget.stream.listen((event) {
setStateHome(event);
});
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Home'),
),
body: FutureBuilder(
future: FirebaseFirestore.instance.collection('users').doc(FirebaseAuth.instance.currentUser!.uid).get(),
builder: (context, snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.none:
case ConnectionState.waiting:
case ConnectionState.active:
return const Center(child: CircularProgressIndicator(),);
case ConnectionState.done:
if (snapshot.hasError) {
return const Center(child: Text('Error'));
}
if (!snapshot.hasData) {
return const Center(child: Text('No Data'),);
}
Map<String, dynamic> data = snapshot.data as Map<String, dynamic>;
List<String> subjects = data['subjects'];
return ListView.builder(
itemCount: subjects.length,
itemBuilder: (context, index) {
return Column(
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: [
const Icon(Icons.book),
const SizedBox(width: 10,),
Text(subjects[index]),
],
),
)
],
);
},
);
}
}
),
floatingActionButton: FloatingActionButton(
onPressed: () {
Navigator.push(context, MaterialPageRoute(builder: (context) {
return const FirstPage();
}));
},
),
);
}
}
// Code for FirstPage
class FirstPage extends StatefulWidget {
const FirstPage({Key? key}) : super(key: key);
#override
State<FirstPage> createState() => _FirstPageState();
}
class _FirstPageState extends State<FirstPage> {
final textController = TextEditingController();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('FirstPage'),
),
body: Column(
children: [
TextField(
controller: textController,
decoration: const InputDecoration(
labelText: 'Subject Name',
hintText: 'Type the subject here',
),
),
TextButton(
onPressed: () async {
await FirebaseFirestore.instance.collection('users').doc(FirebaseAuth.instance.currentUser!.uid)
.update({'subjects' : FieldValue.arrayUnion([textController.text])});
streamControllerHome.add(true);
},
child: const Text('Create Subject')
)
],
)
);
}
}
This is broken:
future: FirebaseFirestore.instance.collection('users').doc(FirebaseAuth.instance.currentUser!.uid).get(),
for reasons given in the first few paragraphs of FutureBuilder documentation, and illustrated in my oft-referenced video https://www.youtube.com/watch?v=sqE-J8YJnpg.
In brief, you cannot build a future as the future: parameter of a FutureBuilder. You need to lift it out into State.
I'm trying to make simple echo WebSocket in Dart with remote server, but it's not work (I don't get echo messages back to me). There is no compile errors or logs. No issues with Flutter Doctor. Rebuild doesn't help.
I could find only outdated examples for localhost and not for server.
Both machines are on the same network and can see each other.
server app code:
import 'dart:io';
void main() async {
HttpServer server = await HttpServer.bind('localhost', 8082);
server.transform(WebSocketTransformer()).listen(onWebSocketData);
}
void onWebSocketData(WebSocket client){
client.listen((data) {
client.add('Echo: $data');
});
}
echo app code:
import 'package:web_socket_channel/web_socket_channel.dart';
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
const title = 'WebSocket Demo';
return const MaterialApp(
title: title,
home: MyHomePage(
title: title,
),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({
Key? key,
required this.title,
}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final TextEditingController _controller = TextEditingController();
final _channel = WebSocketChannel.connect(
Uri.parse('wss://172.22.185.10:8082'),
);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Form(
child: TextFormField(
controller: _controller,
decoration: const InputDecoration(labelText: 'Send a message'),
),
),
const SizedBox(height: 24),
StreamBuilder(
stream: _channel.stream,
builder: (context, snapshot) {
return Text(snapshot.hasData ? '${snapshot.data}' : '');
},
)
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _sendMessage,
tooltip: 'Send message',
child: const Icon(Icons.send),
),
);
}
void _sendMessage() {
if (_controller.text.isNotEmpty) {
_channel.sink.add(_controller.text);
}
}
#override
void dispose() {
_channel.sink.close();
_controller.dispose();
super.dispose();
}
}
I was not able to find any detailed documentation or up-to-date answers, so...
Please help me if you can <3
For server shelf package used
shelf_web_socket: ^1.0.1
Client is mentioned in flutter documentation
Client.dart
import 'package:web_socket_channel/web_socket_channel.dart';
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
const title = 'WebSocket Demo';
return const MaterialApp(
title: title,
home: MyHomePage(
title: title,
),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({
Key? key,
required this.title,
}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final TextEditingController _controller = TextEditingController();
final _channel = WebSocketChannel.connect(
Uri.parse('ws://localhost:9001'),
);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Form(
child: TextFormField(
controller: _controller,
decoration: const InputDecoration(labelText: 'Send a message'),
),
),
const SizedBox(height: 24),
StreamBuilder(
stream: _channel.stream,
builder: (context, snapshot) {
return Text(snapshot.hasData ? '${snapshot.data}' : '');
},
)
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _sendMessage,
tooltip: 'Send message',
child: const Icon(Icons.send),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
void _sendMessage() {
if (_controller.text.isNotEmpty) {
_channel.sink.add(_controller.text);
}
}
#override
void dispose() {
_channel.sink.close();
_controller.dispose();
super.dispose();
}
}
Server.dart
import 'package:shelf/shelf_io.dart' as shelf_io;
import 'package:shelf_web_socket/shelf_web_socket.dart';
void main() {
var handler = webSocketHandler((webSocket) {
webSocket.stream.listen((message) {
webSocket.sink.add("echo $message");
});
});
shelf_io.serve(handler, 'localhost', 9001).then((server) {
print('Serving at ws://${server.address.host}:${server.port}');
});
}
Remote Accessing
Remote accessing not a complicated
in your server side has a firewall . so you need to allow connection to this port( here 9001) for outside acces.Set your server ip in the code instead of localhost in both side like client and server.
Allow port in firewall on windows Os
1
2
3
4
5
6
7
Done.now you can access the port outside.
I'm trying to send a post request and then get some response. This is the site: www.reqres.in and the user data https://reqres.in/api/users.
When I press the Button I don't see any text. Posting name and job to an API and receiving name, id, Datetime and job. If I don't use Widget _showData and show the text in the build below text field then I see the Data, but with a lateInitialization error, but I want to show it using the Widget _showData.
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:http_req_advanced/usermodel.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'HTTP Request 2',
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
var users;
Future<UserModel> createUser(String name, String job) async {
final apiUrl = "https://reqres.in/api/users";
final response =
await http.post(Uri.parse(apiUrl), body: {"name": name, "job": job});
if (response.statusCode == 201) {
users = userModelFromJson(response.body);
} else
throw Exception('Failed to load');
return users;
}
late UserModel user;
final nameController = TextEditingController();
final jobController = TextEditingController();
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
appBar: AppBar(
title: Text('HTTP Request'),
),
body: Container(
padding: EdgeInsets.all(16),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
TextField(
controller: nameController,
),
TextField(
controller: jobController,
),
//Text(
// "The user ${user.name} ${user.id} is created at ${user.createdAt} with job${user.job}"),
ElevatedButton(
onPressed: () async {
final String name = nameController.text;
final String job = jobController.text;
final UserModel userr = await createUser(name, job);
setState(() {
user = userr;
_showData(user.name, user.job, user.id, user.createdAt);
});
},
child: Text('Make a Request'),
),
],
),
),
),
);
}
Widget _showData(String name, String job, String id, DateTime createdat) {
return Container(
alignment: Alignment.bottomCenter,
child: SizedBox(
height: 32,
child:
Text('The user $name [$id] is created at $createdat with job $job'),
),
);
}
}
Instead of using late initialization:
late UserModel user;
Use:
UserModel? user;
When you use late you are declaring a non null variable that will be later initialized, in this case you don't need to use late because user can be null.
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:http_req_advanced/usermodel.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'HTTP Request 2',
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
var users;
Future<UserModel> createUser(String name, String job) async {
final apiUrl = "https://reqres.in/api/users";
final response =
await http.post(Uri.parse(apiUrl), body: {"name": name, "job": job});
if (response.statusCode == 201) {
users = userModelFromJson(response.body);
} else
throw Exception('Failed to load');
return users;
}
late UserModel user;
final nameController = TextEditingController();
final jobController = TextEditingController();
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
appBar: AppBar(
title: Text('HTTP Request'),
),
body: Container(
padding: EdgeInsets.all(16),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
TextField(
controller: nameController,
),
TextField(
controller: jobController,
),
user != null
? _showData(user.name, user.job, user.id, user.createdAt)
: Container(),
//Text(
// "The user ${user.name} ${user.id} is created at ${user.createdAt} with job${user.job}"),
ElevatedButton(
onPressed: () async {
final String name = nameController.text;
final String job = jobController.text;
final UserModel userr = await createUser(name, job);
setState(() {
user = userr;
});
},
child: Text('Make a Request'),
),
],
),
),
),
);
}
Widget _showData(String name, String job, String id, DateTime createdat) {
return Container(
alignment: Alignment.bottomCenter,
child: SizedBox(
height: 32,
child:
Text('The user $name [$id] is created at $createdat with job $job'),
),
);
}
}
I try to use a QR Code Scanner from qr_code_scanner in conjunction with a Webview component webview_flutter.
Everything works fine on iOS but on Android devices it doesn't work, the QR scanner doesn't show and I get a repeated console print.
D/mali_winsys(30667): EGLint new_window_surface(egl_winsys_display *, void *, EGLSurface, EGLConfig, egl_winsys_surface **, EGLBoolean) returns 0x3000
I've tried this on two Android devices (Android 10, v29 and Android 7, v24) with same results.
Below is a minimal app that reproduce the issue. It requires the following dependencies:
qr_code_scanner: ^0.3.5
webview_flutter: ^2.0.2
The code below shows a full-screen webview with a button on-top. Press the button and the QR scanner will/should show up...
import 'package:flutter/material.dart';
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:qr_code_scanner/qr_code_scanner.dart';
import 'package:webview_flutter/webview_flutter.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
bool _showQr = false;
#override
void initState() {
super.initState();
// Enable hybrid composition.
if (Platform.isAndroid) WebView.platform = SurfaceAndroidWebView();
}
void closeQr() {
setState(() {
_showQr = false;
});
}
#override
Widget build(BuildContext context) {
return Stack(
children: [
Stack(
children: [
WebView(
initialUrl: 'https://flutter.dev',
),
Center(
child: TextButton(
onPressed: () {
setState(() {
_showQr = !_showQr;
});
},
child: Text('Show QR Scanner'),
style: TextButton.styleFrom(
primary: Colors.white,
backgroundColor: Colors.teal,
onSurface: Colors.grey,
),
),
),
],
),
Center(
child: (_showQr) ? QRWidget(onClose: closeQr) : null,
),
],
);
}
}
class QRWidget extends StatefulWidget {
const QRWidget({
Key key,
this.onClose,
}) : super(key: key);
final Function onClose;
#override
State<StatefulWidget> createState() => _QRWidgetState();
}
class _QRWidgetState extends State<QRWidget> {
Barcode result;
QRViewController controller;
final GlobalKey qrKey = GlobalKey(debugLabel: 'QR');
// In order to get hot reload to work we need to pause the camera if the platform
// is android, or resume the camera if the platform is iOS.
#override
void reassemble() {
super.reassemble();
if (Platform.isAndroid) {
controller.pauseCamera();
}
controller.resumeCamera();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: <Widget>[
_buildQrView(context),
Container(
alignment: Alignment.bottomCenter,
padding: EdgeInsets.only(bottom: 60.0),
child: Row(
children: <Widget>[
Expanded(
child: RawMaterialButton(
onPressed: () {
setState(() {
widget.onClose();
});
},
elevation: 2.0,
fillColor: Colors.white,
child: Icon(
Icons.close_sharp,
color: Color(0xff459d44),
size: 40.0,
),
padding: EdgeInsets.all(8.0),
shape: CircleBorder(),
),
),
],
),
)
],
),
);
}
Widget _buildQrView(BuildContext context) {
// For this example we check how width or tall the device is and change the scanArea and overlay accordingly.
var scanArea = (MediaQuery.of(context).size.width < 400 ||
MediaQuery.of(context).size.height < 400)
? 150.0
: 300.0;
// To ensure the Scanner view is properly sizes after rotation
// we need to listen for Flutter SizeChanged notification and update controller
return QRView(
key: qrKey,
onQRViewCreated: _onQRViewCreated,
overlay: QrScannerOverlayShape(
borderColor: Color(0xff459d44),
borderRadius: 10,
borderLength: 30,
borderWidth: 10,
cutOutSize: scanArea),
);
}
void _onQRViewCreated(QRViewController controller) {
setState(() {
this.controller = controller;
});
controller.scannedDataStream.listen((scanData) {
setState(() {
result = scanData;
});
});
}
#override
void dispose() {
controller?.dispose();
super.dispose();
}
}
Why doesn't it work on Android?
did you add the permission in AndroidManifest.xml
<uses-permission android:name="android.permission.CAMERA" />
if its webview, why dont you use flutter_inappwebview . Its good to use and has a lot of additional features you may want later. it still needs permission on androidmanifest. Following is the example if you decide to choose flutter_inappwebview.
class _HomePageState extends State<HomePage> {
InAppWebViewController webView;
String url = "";
#override
void initState(){
checkPermissions();
super.initState();
}
#override
void dispose() {
super.dispose();
}
checkPermissions() async{
await [
Permission.camera,
Permission.storage,
].request();
}
#override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
body: SafeArea(
child: Container(
child: Column(children: <Widget>[
Expanded(
child: Container(
child: InAppWebView(
initialUrl: 'https://flutter.dev',
initialHeaders: {},
initialOptions: InAppWebViewGroupOptions(
crossPlatform: InAppWebViewOptions(
debuggingEnabled: true,
)
),
onWebViewCreated: (InAppWebViewController controller) {
webView = controller;
},
onLoadStart: (InAppWebViewController controller, String url) {
setState(() {
this.url = url;
});
},
onLoadStop: (InAppWebViewController controller, String url) async {
setState(() {
this.url = url;
});
},
/// this is the important one to pass the permission
androidOnPermissionRequest: (InAppWebViewController controller, String origin, List<String> resources) async {
return PermissionRequestResponse(resources: resources, action: PermissionRequestResponseAction.GRANT);
},
),
),
),
])
),
),
);
}
}
dont forget to add this permission_handler in your pubspec.yaml
I want to return states to the FutureBuilder from the async task while it's running.
The Task is carProvider.run().
Currently, while waiting for the task to finish, there is a CircularProgressIndicator with a text underneath that display the message string.
And i want to constantly update this message string.
class CarDealerStatefulWidgetState extends State<CarDealerStatefulWidget> {
String _message = "Initialising database and fetching data...";
set setMessage(String message) => setState(() {
_message = message;
});
String get getMessage => _message;
static CarDataProvider carProvider = CarDataProvider();
Future<List<Car>> _requestResult = carProvider.run();
List<Car> items;
String path;
var currentPage;
Widget build(BuildContext context) {
PageController controller;
return DefaultTextStyle(
style: Theme.of(context).textTheme.headline2,
textAlign: TextAlign.center,
child: FutureBuilder<List<Car>>(
future: _requestResult,
builder: (BuildContext context, AsyncSnapshot<List<Car>> snapshot) {
Widget child;
if (snapshot.hasData) {
//
} else if (snapshot.hasError) {
child = Icon(
Icons.error_outline,
color: Colors.red,
size: 60,
);
} else {
child = Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(Colors.green),
),
Padding(
padding: const EdgeInsets.only(top: 20.0),
),
Text(getMessage,
style: TextStyle(
fontSize: 13,
))
I would solve your problem without a FutureProvider but using setState instead.
Check this working example:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
bool _ready = false;
String _text = "";
void changeText(String text) {
setState(() {
_text = text;
});
}
void setReady(bool ready) {
setState(() {
_ready = ready;
});
}
#override
void initState() {
super.initState();
loadData();
}
Future loadData() async {
changeText("initializing...");
await Future.delayed(const Duration(milliseconds: 2000), () => {});
changeText("load settings...");
await Future.delayed(const Duration(milliseconds: 2000), () => {});
changeText("connect to database...");
await Future.delayed(const Duration(milliseconds: 2000), () => {});
changeText("init GUI...");
await Future.delayed(const Duration(milliseconds: 2000), () => {});
setReady(true);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: !_ready
? Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
CircularProgressIndicator(),
Text(_text),
],
)
: Text("OK ready!"),
));
}
}