使用持久颤动包从侧栏抽屉导航到不同的页面,而不使用底部导航栏

问题描述 投票:0回答:1
import 'package:flutter/cupertino.dart';
import 'package:flutter_svg/svg.dart';
import 'package:page_transition/page_transition.dart';
import 'package:persistent_bottom_nav_bar/persistent_tab_view.dart';
import 'package:sizer/sizer.dart';
import 'package:abc/Messages/messages.dart';
import 'package:abc/Vehicles/confirmVehicle.dart';
import 'package:abc/Vehicles/qr_scan_page.dart';
import 'package:abc/pages/common_widgets.dart';
import 'package:abc/pages/dashboard.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

class PersistantWidget extends StatefulWidget {
  const PersistantWidget({super.key});

  @override
  State<PersistantWidget> createState() => _PersistantWidgetState();
}

class _PersistantWidgetState extends State<PersistantWidget> {
  @override
  Widget build(BuildContext context) {
    PersistentTabController _controller =
        PersistentTabController(initialIndex: 0);

    GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();

    List<Widget> _buildScreens() {
      return [
        Dashboard(),
        ConfirmVehicle(),
        QrScanPage(
          toOwnerPage: true,
          addNewVehicle: false,
        ),
        Messages(),
  // Settings(),
      ];
    }

    List<BottomNavigationBarItem> _navBarsItems() {
      return [
        BottomNavigationBarItem(
          label: 'Home',
          icon: Container(
            height: 2.5.h,
            width: 5.5.w,
            child: SvgPicture.asset(
              "assets/images/dashboard_home.svg",
              fit: BoxFit.cover,
              width: 23.49,
              height: 23.49,
            ),
          ),
        ),
        BottomNavigationBarItem(
          label: 'Vehicles',
          icon: Container(
            height: 2.5.h,
            width: 5.5.w,
            child: SvgPicture.asset(
              'assets/images/vehicle.svg',
              fit: BoxFit.cover,
              width: 23.49,
              height: 23.49,
            ),
          ),
        ),
        BottomNavigationBarItem(
          label: '',
          icon: Container(
            height: 2.5.h,
            width: 5.5.w,
            child: SvgPicture.asset(
              "",
              fit: BoxFit.cover,
              width: 23.49,
              height: 23.49,
            ),
          ),
        ),
        BottomNavigationBarItem(
          label: 'Messages',
          icon: Container(
            height: 2.5.h,
            width: 5.5.w,
            child: SvgPicture.asset(
              'assets/images/message.svg',
              fit: BoxFit.cover,
              width: 23.49,
              height: 23.49,
            ),
          ),
        ),
        BottomNavigationBarItem(
          label: 'Settings',
          icon: Container(
            height: 2.5.h,
            width: 5.5.w,
            child: SvgPicture.asset(
              'assets/images/setting.svg',
              fit: BoxFit.cover,
              width: 23.49,
              height: 23.49,
            ),
          ),
        ),
      ];
    }

    return Scaffold(
      key: _scaffoldKey,
      drawer: Drawer(
          backgroundColor: Colors.white,
          elevation: 16.0,
          width: 67.w,
          child: DrawerWidget()),
      body: Stack(
        children: [
          PersistentTabView.custom(
            context,
            controller: _controller,
            screens: _buildScreens(),
            confineInSafeArea: true,
            backgroundColor: Colors.white,
            handleAndroidBackButtonPress: true,
            onWillPop: (BuildContext? context) async {
              return false;
            },
            resizeToAvoidBottomInset: true,
            stateManagement: true,
            hideNavigationBarWhenKeyboardShows: true,
            screenTransitionAnimation: const ScreenTransitionAnimation(
              animateTabTransition: true,
              curve: Curves.ease,
              duration: Duration(milliseconds: 200),
            ),
            customWidget: CustomNavBarWidget(
              items: _navBarsItems(),
              selectedIndex: _controller.index,
              onItemSelected: (index) {
                _controller.index = index;
              },
              scaffoldKey: _scaffoldKey,
              controller: _controller,
            ),
            itemCount: 5,
          ),
          Align(
              alignment: Alignment.bottomCenter,
              child: Container(
                height: 9.h,
                width: 18.w,
                margin: EdgeInsets.only(top: 6.5.h, left: 2.h, right: 2.h),
                child: FloatingActionButton(
                  backgroundColor: Colors.transparent,
                  shape: RoundedRectangleBorder(
                    borderRadius: BorderRadius.circular(50.0),
                  ),
                  onPressed: () {
                    _controller.index = 2;
                  },
                  highlightElevation: 0,
                  tooltip: 'Floating Button',
                  child: SvgPicture.asset(
                    'assets/images/bottomnav_scan.svg',
                    height: 9.h,
                    width: 18.w,
                  ),
                  elevation: 0,
                  materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
                ),
              ))
        ],
      ),
    );
  }
}

class CustomNavBarWidget extends StatelessWidget {
  final int selectedIndex;
  final List<BottomNavigationBarItem> items;
  final ValueChanged<int> onItemSelected;
  final GlobalKey<ScaffoldState> scaffoldKey;
  final PersistentTabController controller; // Add this line

  CustomNavBarWidget({
    super.key,
    required this.selectedIndex,
    required this.items,
    required this.onItemSelected,
    required this.scaffoldKey,
    required this.controller,
  });

  Widget _buildItem(BottomNavigationBarItem item, bool isSelected) {
    return Container(
      alignment: Alignment.center,
      height: 60.0,
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        crossAxisAlignment: CrossAxisAlignment.center,
        mainAxisSize: MainAxisSize.min,
        children: <Widget>[
          Flexible(
            child: IconTheme(
              data: IconThemeData(size: 26.0, color: Colors.grey),
              child: item.icon,
            ),
          ),
          Padding(
            padding: const EdgeInsets.only(top: 5.0),
            child: Material(
              type: MaterialType.transparency,
              child: Text(
                item.label ?? "",
                style: TextStyle(
                    color: Colors.grey,
                    fontFamily: 'Vive Body',
                    fontWeight: FontWeight.w500,
                    fontSize: 7.sp),
              ),
            ),
          )
        ],
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.white,
      child: Container(
        width: double.infinity,
        height: 60.0,
        child: Row(
          mainAxisAlignment: MainAxisAlignment.spaceAround,
          children: items.map((item) {
            int index = items.indexOf(item);
            return Flexible(
              child: GestureDetector(
                onTap: () {
                  if (index == 4) {
                    scaffoldKey.currentState!.openDrawer();
                  } else {
                    onItemSelected(index);
                  }
                },
                child: _buildItem(item, selectedIndex == index),
              ),
            );
          }).toList(),
        ),
      ),
    );
  }
}

我们正在使用持久底部导航栏 flutter 包。它工作得很好,但是当我们从侧抽屉调用特定页面(例如“联系我们”)时,它会将我们重定向到“联系我们”页面,但我们失去了持久的底部导航栏。

但是我们从底部导航栏重定向,我们并没有松开底部导航栏。

flutter navigation slidingdrawer
1个回答
0
投票

实现起来非常简单。

首先让我向您展示我的解决方法

包含 sideNavDrawer 执行的所有操作的枚举(不要从侧面导航抽屉执行操作)根据您的应用程序更改它们

enum SideNavActions {
  close,
  nearByTechnicians,
  myRequests,
  payments,
  support,
  rateYourTechnician,
  logout,
}

然后将函数传递到您的 DrawerWidget 中,如下所示

class SideNavDrawer extends StatefulWidget {
  final Function(SideNavActions) callback; // <--- callback function
  const SideNavDrawer({
    Key? key,
    required this.callback,
  }) : super(key: key);

  @override
  State<SideNavDrawer> createState() => _SideNavDrawerState();
}

现在您将在 SideNavDrawerItem 小部件中调用此回调函数,如下所示(下面是我的应用程序的示例)

    ListTile(
      onTap: () {
        // this is callback function
        widget.callback(SideNavActions.nearByTechnicians);
      },
      leading: Image.asset(
        'assets/icons/map_marker.png',
        color: AppColors.white,
        width: 25,
        height: 25,
      ),
      title: const Text('Nearby Technicians'),
    ),

现在让我们回到您的 DrawerWidget,您需要像这样将该回调函数传递到您的 DrawerWidget 中

drawer: SideNavDrawer(
            callback: (p0) {
              viewModel.sideNavCallBack(p0);
            },
          ),

现在什么是 viewModel.sideNavCallBack(p0) 函数,这个函数实际上会监听你的回调函数(忽略 viewModel 因为我遵循 MVVM 设计模式)你可以将该函数写入你的 PersistantWidget

现在在 sideNavCallBack 函数中编写导航逻辑

  void sideNavCallBack(SideNavActions action) {
    if (action == SideNavActions.close) {
      advancedDrawerController.hideDrawer();
    } else if (action == SideNavActions.nearByTechnicians) {
      advancedDrawerController.hideDrawer();
// just focus on this below function selectPage(index), this function is used to update the page when user click on an item on bottomNavigation bar 
      selectPage(1);
    } else if (action == SideNavActions.myRequests) {
      advancedDrawerController.hideDrawer();
      _nav.pushNamed(myRequestsViewRoute);
    } else if (action == SideNavActions.payments) {
    } else if (action == SideNavActions.support) {
      advancedDrawerController.hideDrawer();
      _nav.pushNamed(supportViewRoute);
    } else if (action == SideNavActions.rateYourTechnician) {
    } else if (action == SideNavActions.logout) {
      logoutAlert();
    }
  }

看示范

© www.soinside.com 2019 - 2024. All rights reserved.