Vivian Lobo
Vivian Lobo

Reputation: 623

Flutter initState does not run the method called

I am sure I am missing something quite obvious but, just not able to understand why is this happening.

I call a method called readJSON which reads a JSON file into an object. I use the length to render the pages and each page has a list of checkboxes based on the index of main object.

I have used: https://github.com/afzalali15/onboarding_demo to build this Onboarding task within my app.

*Just to note, while I was implementing this, I saw the hot reload work perfectly fine. When I closed VSCode and opened it again later, readJSON method never runs.

class _OnboardingPageState extends State<OnboardingPage> {
  List<OnboardingTodo> onboardingTasks = [];
  final _controller = OnboardingController();
  String response = '';

  bool value = false;

  Future<void> readJson() async {
    response = await rootBundle.loadString('assets/cfg/onboarding_tasks.json');
    final onboardingTodo = onboardingTodoFromJson(response);
    onboardingTasks.addAll(onboardingTodo.values);
    print("onboarding length - " + onboardingTasks.length.toString());
  }

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Stack(
          children: [
            PageView.builder(
              controller: _controller.pageController,
              onPageChanged: _controller.selectedPageIndex,
              itemCount: onboardingTasks.length,
              itemBuilder: (context, index) {
                return Container(
                  child: Column(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: [
                      Image.asset(
                        _controller.onboardingPages[index].imageAsset,
                        height: 100,
                        width: 100,
                      ),
                      SizedBox(height: 32),
                      Text(
                        _controller.onboardingPages[index].title,
                        style: TextStyle(
                            fontSize: 24, fontWeight: FontWeight.w500),
                      ),
                      SizedBox(height: 32),
                      Expanded(
                        child: Container(
                          child: ListView.builder(
                            padding: const EdgeInsets.all(8),
                            itemCount: onboardingTasks[index].tasks.length,
                            itemBuilder:
                                (BuildContext context, int chkBoxindex) {
                              return CheckboxListTile(
                                controlAffinity:
                                    ListTileControlAffinity.leading,
                                value: value,
                                title: Text(
                                    '${onboardingTasks[index].tasks[chkBoxindex].title}'),
                                onChanged: (bool newVal) {
                                  setState(() {
                                    value = newVal;
                                  });
                                },
                              );
                            },
                          ),
                        ),
                      ),
                    ],
                  ),
                );
              },
            ),
            // The dots showing the index of the pages
            ...
            // The next/end button
            ...
          ],
        ),
      ),
    );
  }
}

Any help, or suggestions is appreciated. Thanks

Upvotes: 1

Views: 5615

Answers (1)

novol
novol

Reputation: 852

try

void initState() {     
  super.initState();     
  WidgetsBinding.instance.addPostFrameCallback((_) => readJson(););   
}

or Use Loader like

bool loading = true;
  Future<void> readJson() async {
    setState(() => loading = true);
    response = await rootBundle.loadString('assets/cfg/onboarding_tasks.json');
    final onboardingTodo = onboardingTodoFromJson(response);
    onboardingTasks.addAll(onboardingTodo.values);
    print("onboarding length - " + onboardingTasks.length.toString());
    setState(() => loading = false);
  }

and put loader into UI like

itemBuilder: (context, index) {
                return loading ? YourProgressIndicatorWidget : Container(child: ......
}

Upvotes: 1

Related Questions