fluttertabview

how to conditionally pass multiple widget for flutter tabBarview


enter image description hereI have a tabview that I want to pass multiple widget to it depending on which screen the user navigated to. The first screen only contains two children while the other one contains four children. I have conditionally passed four Widgets to the other one but it only picked three meaning that my conditions are wrong and it's also giving me this error. Controller's length property (4) does not match the number of children (3) present in TabBarView's children property.

From the attached image, you will see that I tapped on the Archdiocese text and it's returning me the national screen which supposed not to be so.
I really need help on how to navigate them all sequentially
The Paytype there is just an enum

 Expanded(
                child: Container(
                  clipBehavior: Clip.hardEdge,
                  margin: EdgeInsets.symmetric(
                    horizontal: context.smallPadding,
                  ),
                  decoration: const BoxDecoration(
                    borderRadius: BorderRadius.only(
                      topLeft: Radius.circular(cornerRadius),
                      topRight: Radius.circular(cornerRadius),
                    ),
                    color: white,
                  ),
                  child: DefaultTabController(
                    length: 4,
                    child: Scaffold(
                      extendBodyBehindAppBar: true,
                      resizeToAvoidBottomInset: false,
                      backgroundColor: white,
                      appBar: AppBar(
                        elevation: 0,
                        toolbarHeight: 0,
                        backgroundColor: white,
                        bottom: TabBar(
                          indicatorColor: AppColor.kColor700,
                          labelColor: AppColor.kColor700,
                          isScrollable: true,
                          padding: const EdgeInsets.only(
                            bottom: 10.0,
                          ),
                          labelPadding:
                              const EdgeInsets.symmetric(horizontal: 10),
                          indicatorPadding: EdgeInsets.zero,
                          indicatorSize: TabBarIndicatorSize.label,
                          unselectedLabelColor: Colors.grey,
                          labelStyle: TextStyles.t3.copyWith(
                            fontSize: FontSizes.s14,
                          ),
                          unselectedLabelStyle: TextStyles.t3.copyWith(
                            fontSize: FontSizes.s14,
                          ),
                          tabs: [
                            const Text('All parishes'),
                            if (widget.payType != PayType.paygroup) ...[
                              const Text('Favorite parishes'),
                            ] else ...[
                              const Text('Favorite groups'),
                              const Text('ArchDiocese'),
                              const Text("National")
                            ],
                          ],
                        ),
                      ),
                      body: TabBarView(
                        children: [
                          //All parishes
                          BlocProvider(
                            create: (context) => sl<BeneficiaryBloc>(),
                            child: PageParishes(
                              payType: widget.payType,
                              onPressed: (parish) {
                                if (widget.payType == PayType.payparish) {
                                  //Navigate to a payparish screen
                                  Navigator.push(
                                    context,
                                    CustomRoute(
                                      child: MultiBlocProvider(
                                        providers: [
                                          BlocProvider(
                                            create: (context) =>
                                                sl<BeneficiaryBloc>(),
                                          ),
                                          BlocProvider(
                                            create: (context) => sl<HomeBloc>(),
                                          ),
                                        ],
                                        child: PagePayParish(
                                          parish: parish,
                                        ),
                                      ),
                                    ),
                                  );
                                } else {
                                  //Navigate to a parish groups screen
                                  Navigator.push(
                                    context,
                                    CustomRoute(
                                      child: PageGroups(
                                        parish: parish,
                                      ),
                                    ),
                                  );
                                }
                              },
                            ),
                          ),
                          //Groups
                          widget.payType != PayType.paygroup
                              ? PageRecentParishes(
                                  onPressed: (parish) {
                                    //check if it's parish
                                    if (widget.payType == PayType.payparish) {
                                      //Navigate to a payparish screen
                                      Navigator.push(
                                        context,
                                        CustomRoute(
                                          child: MultiBlocProvider(
                                            providers: [
                                              BlocProvider(
                                                create: (context) =>
                                                    sl<BeneficiaryBloc>(),
                                              ),
                                              BlocProvider(
                                                create: (context) =>
                                                    sl<HomeBloc>(),
                                              ),
                                            ],
                                            child: PagePayParish(
                                              parish: parish,
                                            ),
                                          ),
                                        ),
                                      );
                                    }
                                    else {
                                      //Navigate to a parish groups screen
                                      Navigator.push(
                                        context,
                                        CustomRoute(
                                          child: PageGroups(
                                            parish: parish,
                                          ),
                                        ),
                                      );
                                    }
                                  },
                                )
                              :PageRecentGroups(
                            onPressed: (parishGroup) {
                              //navigate to paygroups
                              Navigator.push(
                                context,
                                CustomRoute(
                                  child: MultiBlocProvider(
                                    providers: [
                                      BlocProvider(
                                        create: (context) =>
                                            sl<BeneficiaryBloc>(),
                                      ),
                                      BlocProvider(
                                        create: (context) =>
                                            sl<HomeBloc>(),
                                      ),
                                    ],
                                    child: PagePayGroup(
                                      parishGroup: parishGroup,
                                    ),
                                  ),
                                ),
                              );
                            },
                          ),
                          widget.payType !=PayType.paygroup?const PageArchDiocese():const PageNationalGroup()
                          //National and Archdiocesan groups

                        ],
                      ),
                    ),
                  ),
                ),
              ),

Solution

  • Could you use an array of tab models to keep your tab metadata together? Something like this:

    class TabModel {
      const TabModel({
        required this.title,
        required this.child,
      });
    
      final String title;
      final Widget child;
    }
    
    @override
    Widget build(BuildContext context) {
      final tabs = [
        TabModel(title:'All parishes', child: AllParishesWidget()),
        if (widget.payType != PayType.paygroup) ...[
          TabModel(title:'Favorite parishes', child FavoriteParishesWidget()),
        ] else ...[
          TabModel(title: 'Favorite groups', child: FavoriteGroupsWidget()),
          TabModel(title: 'ArchDiocese', child: ArchdioceseWidget()),
          TabModel(title: 'National', child: NationalWidget())
        ],
      ];
      
      Expanded(
        child: Container(
          ...
          child: DefaultTabController(
            ...
              tabs: tabs.map((tab) => Text(tab.title)).toList(),
            ...
            body: TabBarView(
              children: tabs.map((tab) => tab.child).toList(),
            ),
          ),
        ),
    }