The home screen is displayed before the walkthrough is displayed

Viewed 38

I am trying to implement a walkthrough screen to be displayed when the system is first started.

The shared_preference package is used in initState to determine if it is the first time it is started.

When I execute the following code (simplified), it transitions to the waklThrou screen, but the home screen is displayed for a moment.

Do you have any good ideas?

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutterapp/ui/pages/walk/walk_through_page.dart';
import 'package:shared_preferences/shared_preferences.dart';

class RootPage extends StatefulWidget {
  @override
  _RootPageState createState() => _RootPageState();
}

class _RootPageState extends State<RootPage> {
  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addPostFrameCallback((_) async {
      final prefs = await SharedPreferences.getInstance();
      if (prefs.getBool('isFirstLaunch') ?? true) {
        Navigator.push(
          context,
          MaterialPageRoute(builder: (context) => WalkThroughPage()),
        );
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return Consumer(
      builder: (ctx, watch, _) {
        return WillPopScope(
            onWillPop: () async => false,
            child: Scaffold(
              appBar: AppBar(),
              body: Container(
                decoration: new BoxDecoration(
                  image: new DecorationImage(
                    image: AssetImage('images/back_ground.png'),
                    fit: BoxFit.cover,
                  ),
                ),
                child: Center(child: Text('Home')),
              ),
            ));
      },
    );
  }
}
2 Answers

Since the WidgetsBinding.instance.addPostFrameCallback is a callback, that code will be passed and the build method will be executed.

Once the callback is invoked, the Navigator will push the new screen.

One easy solution to avoid the home screen showing would be to just add a loading indicator in the body. And a stateful variable in the callback that will change the loading state when it's finished.

Another option is to hold the state of completion of the walkthrough screen outside of the widget (eg in a BLOC) using a Completer, eg Completer walkThrough and in your main widget use a FutureBuilder that builds either a blank page (if the walkThrough Future has not yet completed) or the home screen (if it has). See FutureBuilder for an example of this UI paradigm.

In the BLOC you create the walkThrough completer upon start-up, check prefs and either

  • trigger the walkthrough screen and, upon completion of the walkthrough, complete the walkThrough completer using walkThrough.complete() and pop the UI back to the home screen, or
  • immediately complete the completer if you found the walkthrough is finished.

See Completer for the idea behind those.

Related