setState() или markNeedsBuild(), вызываемые во время сборки CupertinoTabScaffold

У меня есть код, использующий CupertinoTabScaffold для отображения нижней навигации, я хочу отобразить нижний диалоговый лист в одном из меню, но получаю сообщение об ошибке

Следующее утверждение было выброшено сборщиком сборки (грязный, зависимости: [_InheritedTheme, _LocalizationsScope-[GlobalKey#a6d51]]): setState() или markNeedsBuild(), вызываемые во время сборки.

это мой код

class AppTab extends StatefulWidget {
final dataUser;
AppTab(this.dataUser);

@override
_AppTabState createState() => _AppTabState(dataUser);
}

class _AppTabState extends State<AppTab> {
final user;
_AppTabState(this.user);

 @override
Widget build(BuildContext context) {
return BlocListener<AuthenticationBloc, AuthenticationState>(
  listener: (context, state) {
    if (state == AuthenticationState.unauthenticated()) {
      Navigator.pushNamedAndRemoveUntil(context, '/login', (route) => false, arguments: state.loginPageState);
    }
  },
  child: CupertinoTabScaffold(
    controller: tabController,
    tabBar: CupertinoTabBar(
      activeColor: HexColor("#26ADE4"),
      inactiveColor: HexColor("#707070"),
      items: [
        BottomNavigationBarItem(
          label: "Menu 1",
          icon: Image.asset("assets/icon_tab_home.png", height: 25, width: 22),
          activeIcon: Image.asset("assets/icon_tab_home_active.png", height: 25, width: 22),
        ),
        BottomNavigationBarItem(
          label: "Menu 2",
          icon: Image.asset("assets/icon_tab_buat_bill.png", height: 25, width: 22),
          activeIcon: Image.asset("assets/icon_tab_buat_bill_active.png", height: 25, width: 22),
        ),
        BottomNavigationBarItem(
          label: "Menu 3",
          icon: Image.asset("assets/icon_tab_account.png", height: 25, width: 22),
          activeIcon: Image.asset("assets/icon_tab_account_active.png", height: 25, width: 22),
        ),
      ],
    ),
    tabBuilder: (context, index) {
      if (index == 0) {
        return HomePage(user);
      } else if (index == 1) {
        return _bottomSheetMore(context);
      }
      return AccountPage(user);
    }),
);
}

_bottomSheetMore(context) {
showModalBottomSheet(
  context: context,
  builder: (builder) {
    return new Container(
      padding: EdgeInsets.only(
        left: 5.0,
        right: 5.0,
        top: 5.0,
        bottom: 5.0,
      ),
      decoration: new BoxDecoration(
          color: Colors.white,
          borderRadius: new BorderRadius.only(
              topLeft: const Radius.circular(10.0),
              topRight: const Radius.circular(10.0))),
      child: new Wrap(
        children: <Widget>[
          new ListTile(
            title: const Text(
              'Menu Akun',
              style: TextStyle(
                fontSize: 14.0,
                fontWeight: FontWeight.w700,
              ),
            ),
            subtitle: Text("Pilih salah satu"),
          ),
          new Divider(
            height: 10.0,
          ),
          new ListTile(
            title: const Text(
              'Menu Home',
              style: TextStyle(
                fontSize: 14.0,
                fontWeight: FontWeight.w700,
              ),
            ),
          ),
          new Divider(
            height: 10.0,
          ),
          new ListTile(
            title: const Text(
              'Logout',
              style: TextStyle(
                fontSize: 14.0,
                fontWeight: FontWeight.w700,
              ),
            ),
            onTap: () async {
              // Add Here
            },
          ),
        ],
      ),
    );
  },
);
 }
 }

person Rohmatul Laily    schedule 09.03.2021    source источник


Ответы (1)


Он отображает эту ошибку, потому что виджет должен быть нарисован перед отображением модального нижнего листа. Чтобы отобразить ваш модальный нижний лист, вызовите его внутри Future.delayed(...).

Вы можете попробовать что-то вроде этого.

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

void main() => runApp(MaterialApp(home: AppTab()));

class AppTab extends StatefulWidget {
  @override
  _AppTabState createState() => _AppTabState();
}

class _AppTabState extends State<AppTab> {
  final CupertinoTabController _controller = CupertinoTabController();
  final List<CupertinoPageScaffold> _pages = <CupertinoPageScaffold>[
    CupertinoPageScaffold(
      child: const Center(child: Text('Home Page')),
    ),
    CupertinoPageScaffold(
      child: const Center(child: Text('2nd Page')),
    ),
    CupertinoPageScaffold(
      child: const Center(child: Text('Account Page')),
    ),
  ];

  bool _isBottomSheetShown = false;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: CupertinoTabScaffold(
        controller: _controller,
        tabBar: CupertinoTabBar(
          activeColor: Colors.red,
          inactiveColor: Colors.blue,
          items: const [
            BottomNavigationBarItem(
              label: "Menu 1",
              icon: Icon(Icons.ac_unit),
            ),
            BottomNavigationBarItem(
              label: "Menu 2",
              icon: Icon(Icons.local_activity),
            ),
            BottomNavigationBarItem(
              label: "Menu 3",
              icon: Icon(Icons.assessment),
            ),
          ],
        ),
        tabBuilder: (context, index) {
          return CupertinoTabView(
            builder: (BuildContext context) {
              if (_controller.index == 1 && index == 1) {
                _bottomSheetMore(context);
              }

              return _pages[index];
            },
          );
        },
      ),
    );
  }

  Future<void> _bottomSheetMore(context) async {
    if (_isBottomSheetShown) {
      return;
    }

    _isBottomSheetShown = true;

    await Future<void>.delayed(
      const Duration(milliseconds: 10),
      () => showModalBottomSheet<void>(
        context: context,
        builder: (_) {
          return Container(
            height: 300,
            padding: const EdgeInsets.all(5),
            decoration: const BoxDecoration(
              color: Colors.white,
              borderRadius: BorderRadius.only(
                topLeft: const Radius.circular(10.0),
                topRight: const Radius.circular(10.0),
              ),
            ),
            child: Wrap(
              children: <Widget>[
                ListTile(
                  title: const Text(
                    'Menu Akun',
                    style: TextStyle(
                      fontSize: 14.0,
                      fontWeight: FontWeight.w700,
                    ),
                  ),
                  subtitle: const Text("Pilih salah satu"),
                ),
                const Divider(height: 10.0),
                ListTile(
                  title: const Text(
                    'Menu Home',
                    style: TextStyle(
                      fontSize: 14.0,
                      fontWeight: FontWeight.w700,
                    ),
                  ),
                ),
                const Divider(height: 10.0),
                ListTile(
                  title: const Text(
                    'Logout',
                    style: TextStyle(
                      fontSize: 14.0,
                      fontWeight: FontWeight.w700,
                    ),
                  ),
                  onTap: () async {
                    // Add Here
                  },
                ),
              ],
            ),
          );
        },
      ),
    );

    _isBottomSheetShown = false;
  }

  @override
  void dispose() {
    super.dispose();
    _controller.dispose();
  }
}
person rickimaru    schedule 09.03.2021