Kingsley CA
Kingsley CA

Reputation: 11624

Flutter - Complex functions in initState() slowing down navigation and performance

I am working on this app, where you can navigate to a screen with a stateful widget that has a bunch complex functions that run in initState().

Due to these functions, navigating to this screen takes close to two seconds after the Navigation function is triggered i.e It is very slow

My Code looks like this

@override
void initState(){
  someComplexHeavyFunctions();      

  super.initState();
}   

Is there any way to make sure the navigation has completed (fast and smmothly) before running the function in initState() and also, maybe showing a loader while the functions are still processing after the screen has been navigated to?

like this:

enter image description here

Upvotes: 1

Views: 1751

Answers (2)

chemamolins
chemamolins

Reputation: 20558

You can call the initializing function and while awaiting for it, display the dialog.

This is a complete example:

import 'dart:async';

import 'package:flutter/material.dart';

void main() => runApp(new MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Flutter Demo',
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: new MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text("Test"),
      ),
      body: new Center(
        child: FloatingActionButton(
          child: Text("Go"),
          onPressed: () {
            Navigator.of(context)
                .push(MaterialPageRoute(builder: (_) => OtherPage()));
          },
        ),
      ),
    );
  }
}

class OtherPage extends StatefulWidget {
  @override
  _OtherPageState createState() => _OtherPageState();
}

class _OtherPageState extends State<OtherPage> {
  bool initialized = false;

  @override
  void initState() {
    super.initState();

    initialize();

    WidgetsBinding.instance.addPostFrameCallback((_) async {
      await showDialog<String>(
        context: context,
        builder: (BuildContext context) => new AlertDialog(
              content: Column(
                mainAxisSize: MainAxisSize.min,
                children: <Widget>[
                  CircularProgressIndicator(),
                  SizedBox(height: 40.0,),
                  Text("Performing task"),
                ],
              ),
            ),
      );
    });
  }

  Future<void> initialize() async {
    initialized = await Future.delayed(Duration(seconds: 5), () => true);
    Navigator.of(context).pop();
    setState(() {});
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(),
      body: new Center(
        child: initialized ? Text("Initialized") : Container(),
      ),
    );
  }
}

Upvotes: 3

G&#252;nter Z&#246;chbauer
G&#252;nter Z&#246;chbauer

Reputation: 657338

You can use the compute function to do the calculation in a different isolate which runs on a different thread.

Upvotes: 3

Related Questions