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 包。它工作得很好,但是当我们从侧抽屉调用特定页面(例如“联系我们”)时,它会将我们重定向到“联系我们”页面,但我们失去了持久的底部导航栏。
但是我们从底部导航栏重定向,我们并没有松开底部导航栏。
实现起来非常简单。
首先让我向您展示我的解决方法
包含 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();
}
}