在页面视图之间导航时如何保留底部导航

时间:2021-04-01 07:16:20

标签: flutter dart

我有 4 个页面,一个带有各自底部导航器的页面视图,在第一个索引处,我正在执行一个导航到第 4 页的函数。但是,导航后,底部导航消失,这是不一致的。我如何使它保持一致..,

class HomePage extends StatefulWidget {
  HomePage({
    Key key,
    this.category,
    this.shopname,
  }) : super(key: key); //update this to   include the uid in the constructor
  final String shopname;
  final DocumentSnapshot category;

  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {

页面控制器,

  PageController _tabsPageController;
  int _selectedTab = 0;

  @override
  void initState() {
    _tabsPageController = PageController();
    super.initState();
  }

  @override
  void dispose() {
    _tabsPageController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: [
          Expanded(
            child: PageView(
              controller: _tabsPageController,
              onPageChanged: (num) {
                setState(() {
                  _selectedTab = num;
                });
              },
              children: [

登陆页面的导航

                LandingPage(), //<<================
                SavedTab(
                  shopname: widget.shopname,
                ),
                MyDrawer(),

导航到主页()

                HomeTab()      //<<================
              ],
            ),
          ),
          BottomTabs(
            selectedTab: _selectedTab,
            tabPressed: (num) {
              _tabsPageController.animateToPage(num,
                  duration: Duration(milliseconds: 300),
                  curve: Curves.easeOutCubic);
            },
          ),
        ],
      ),
    );
  }
}

2 个答案:

答案 0 :(得分:0)

您实际上只需要路由到所需页面的底部导航栏。它基本上呈现了底部导航栏小部件内的所有屏幕,因此底部导航栏始终显示。下面是一个例子:

class BottomNavBar extends StatefulWidget {
  @override
  _BottomNavBarState createState() => _BottomNavBarState();
}

class _BottomNavBarState extends State<BottomNavBar> {
  int _selectedIndex = 0;
  static List<Widget> _widgetOptions = <Widget>[
    Screen1(),
    Screen2(),
Screen3(),
  ];

  void _onItemTapped(int index) {
    setState(() {
      _selectedIndex = index;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: _widgetOptions.elementAt(_selectedIndex),
      ),
      bottomNavigationBar: BottomNavigationBar(
        items: <BottomNavigationBarItem>[
          BottomNavigationBarItem(
            icon: Icon(Icons.dashboard),
            label: 'Screen 1',
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.work),
            label: 'Screen 2',
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.directions_car),
            label: 'Screen 3',
          ),
        ],
        currentIndex: _selectedIndex,
        onTap: _onItemTapped,
      ),
    );
  }
}

如果它适合你,请在评论中告诉我。

答案 1 :(得分:0)

检查我的代码

自定义脚手架

class AppScaffold extends StatefulWidget {
  final List<BottomNavigationBarItem> items;
  final List<AppScaffoldWidgetBuilder> builders;

  const AppScaffold({
    Key? key,
    required this.items,
    required this.builders,
  }) : super(key: key);

  @override
  _AppScaffoldState createState() => _AppScaffoldState();

  static NavigatorState navigatorOfCurrentIndex(
    BuildContext context, {
    AppScaffoldIndex? switchToNewIndex,
  }) {
    final appScaffoldState =
        context is StatefulElement && context.state is _AppScaffoldState
            ? context.state as _AppScaffoldState
            : context.findAncestorStateOfType<_AppScaffoldState>()!;

    final currentIndex = appScaffoldState.currentIndex;
    final navigatorKeys = appScaffoldState.navigatorKeys;
    final newIndex = switchToNewIndex?.rawValue;

    if (newIndex != null &&
        newIndex != currentIndex &&
        appScaffoldState.mounted) {
      appScaffoldState.onTap(newIndex);
      return navigatorKeys[newIndex].currentState!;
    }

    return navigatorKeys[currentIndex].currentState!;
  }

  static NotReplayValueStream<AppScaffoldIndex> currentIndexStream(
          BuildContext context) =>
      context.findAncestorStateOfType<_AppScaffoldState>()!.indexS;

  static NavigatorState navigatorByIndex(
    BuildContext context,
    AppScaffoldIndex index,
  ) {
    final appScaffoldState =
        context.findAncestorStateOfType<_AppScaffoldState>()!;
    return appScaffoldState.navigatorKeys[index.rawValue].currentState!;
  }
}

class _AppScaffoldState extends State<AppScaffold> with DisposeBagMixin {
  var navigatorKeys = <GlobalKey<NavigatorState>>[];
  final indexS = ValueSubject(AppScaffoldIndex.home, sync: true);

  @pragma('vm:prefer-inline')
  @pragma('dart2js:tryInline')
  int get currentIndex => indexS.requireValue.rawValue;

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

    navigatorKeys = List.generate(
      widget.builders.length,
      (_) => GlobalKey<NavigatorState>(),
    );
    indexS.disposedBy(bag);
  }

  @override
  Widget build(BuildContext context) {
    return WillPopScope(
      onWillPop: () {
        final navigatorState = navigatorKeys[currentIndex].currentState!;
        final canPop = navigatorState.canPop();

        if (canPop) {
          navigatorState.maybePop();
        }

        if (!canPop && currentIndex > 0) {
          onTap(0);
          return Future.value(false);
        }

        return Future.value(!canPop);
      },
      child: RxStreamBuilder<AppScaffoldIndex>(
        stream: indexS,
        builder: (context, snapshot) {
          final index = snapshot!.rawValue;

          return Scaffold(
            body: buildBody(index),
            bottomNavigationBar: BottomNavigationBar(
              items: widget.items,
              type: BottomNavigationBarType.fixed,
              currentIndex: index,
              onTap: onTap,
            ),
          );
        },
      ),
    );
  }

  void onTap(final int newIndex) {
    if (currentIndex == newIndex) {
      navigatorKeys[currentIndex]
          .currentState
          ?.popUntil((route) => route.isFirst);
    } else {
      indexS.add(_fromRawValue(newIndex));
    }
  }

  Widget buildBody(int index) {
    return IndexedStack(
      index: index,
      children: [
        for (int i = 0; i < widget.builders.length; i++)
          Navigator(
            key: navigatorKeys[i],
            onGenerateRoute: (settings) => MaterialPageRoute(
              settings: settings,
              builder: (context) => widget.builders[i](context, settings),
            ),
            observers: [
              HeroController(),
            ],
          )
      ],
    );
  }
}

首页

return AppScaffold(
      key: appScaffoldKey,
      builders: [
        (context, settings) => homeRoutes[settings.name]!(context, settings),
        (context, settings) =>
            favoritesRoutes[settings.name]!(context, settings),
        (context, settings) =>
            notificationsRoutes[settings.name]!(context, settings),
        (context, settings) => profileRoutes[settings.name]!(context, settings),
      ],
      items: [
        BottomNavigationBarItem(
          icon: const Icon(Icons.home_rounded),
          label: S.of(context).home,
        ),
        BottomNavigationBarItem(
          icon: const Icon(Icons.favorite_rounded),
          label: S.of(context).favorites,
        ),
        BottomNavigationBarItem(
          icon: const Icon(Icons.notifications),
          label: S.of(context).notifications,
        ),
        BottomNavigationBarItem(
          icon: const Icon(Icons.person_rounded),
          label: S.of(context).profile,
        ),
      ],
    );