Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
286 views
in Technique[技术] by (71.8m points)

dart - Flutter Wait for the Notifier's constructor to be initiated

I'm trying to display in a listView builder a list that I load when initializing my constructor. This doesn't work right now because the listView runs before the constructor has finished loading my list.

How to do ?

My Notifier:

class TablesNotifier with ChangeNotifier {

  // Services
  // ---------------------------------------------------------------------------
  final jsonSelectorService = locator<JsonSelectorService>();

  // Variables
  // ---------------------------------------------------------------------------
  List<AltitudeModel> altitudes;

  // Constructor
  // ---------------------------------------------------------------------------
  TablesNotifier(){
    _initialise();
  }

  // Initialisation
  // ---------------------------------------------------------------------------
  Future _initialise() async{
    print('--- initialise');
    altitudes = await jsonSelectorService.altitudes();
  }
}

My screen:

class TableScreen extends StatelessWidget {
  final String title;
  TableScreen({Key key, @required this.title}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: _buildBody(context),
    );
  }
  
  Widget _buildBody(BuildContext context)
  {
    var _tableProvider = Provider.of<TablesNotifier>(context);
    return ListView.builder(
      itemCount: _tableProvider.altitudes.length,
      itemBuilder: (context, index) {
        return ListTile(
          title: Text('${_tableProvider.altitudes[index]}'),
        );
      },
    );
  }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You can copy paste run full code below
I use 7 seconds delay to simulate jsonSelectorService
Step 1: You can check _tableProvider.altitudes == null and return CircularProgressIndicator() or ListView
Step 2: when altitudes data is ready call notifyListeners()
code snippet

Future _initialise() async {
    print('--- initialise');
    await Future.delayed(Duration(seconds: 7), () {});
    altitudes = [
      AltitudeModel(title: "1"),
      AltitudeModel(title: "2"),
      AltitudeModel(title: "3"),
      AltitudeModel(title: "4"),
      AltitudeModel(title: "5")
    ];

    notifyListeners();
  }
  
Widget _buildBody(BuildContext context) {
    var _tableProvider = Provider.of<TablesNotifier>(context);
    return _tableProvider.altitudes == null
        ? Center(child: CircularProgressIndicator())
        : ListView.builder(

working demo

enter image description here

full code

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider(
      create: (context) => TablesNotifier(),
      builder: (context, child) => MaterialApp(
        home: TableScreen(),
      ),
    );
  }
}

class AltitudeModel {
  String title;

  AltitudeModel({this.title});
}

class TablesNotifier with ChangeNotifier {
  // Services
  // ---------------------------------------------------------------------------
  //final jsonSelectorService = locator<JsonSelectorService>();

  // Variables
  // ---------------------------------------------------------------------------
  List<AltitudeModel> altitudes;

  // Constructor
  // ---------------------------------------------------------------------------
  TablesNotifier() {
    _initialise();
  }

  // Initialisation
  // ---------------------------------------------------------------------------
  Future _initialise() async {
    print('--- initialise');
    await Future.delayed(Duration(seconds: 7), () {});
    altitudes = [
      AltitudeModel(title: "1"),
      AltitudeModel(title: "2"),
      AltitudeModel(title: "3"),
      AltitudeModel(title: "4"),
      AltitudeModel(title: "5")
    ];

    notifyListeners();
  }
}

class TableScreen extends StatelessWidget {
  final String title;
  TableScreen({Key key, @required this.title}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: _buildBody(context),
    );
  }

  Widget _buildBody(BuildContext context) {
    var _tableProvider = Provider.of<TablesNotifier>(context);
    return _tableProvider.altitudes == null
        ? Center(child: CircularProgressIndicator())
        : ListView.builder(
            itemCount: _tableProvider.altitudes.length,
            itemBuilder: (context, index) {
              return ListTile(
                title: Text('${_tableProvider.altitudes[index].title}'),
              );
            },
          );
  }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

57.0k users

...