如何解决从一种活动转到另一种活动时颤振如何使bottomnavigationbar保持恒定
我有一个带有bottomnavigationbar的页面,单击每个图标可以转到3个不同的页面。我的代码运行正常,但我希望在从一页路由到另一页时保持导航的底部。下面是我的代码:
class Home extends StatefulWidget {
@override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
int currentTab = 0;
final List<Widget> screens = [
DealActivity(),FinalLoginPage(),ProfilePageUsers(),];
final PageStorageBucket bucket = PageStorageBucket();
Widget currentScreen = DealActivity(); // Our first view in viewport
@override
Widget build(BuildContext context) {
const assetHome = 'assets/home_off.svg';
const assetRedemptions = 'assets/redeemed_off.svg';
const assetProfile = 'assets/profile_off.svg';
const assetHome1 = 'assets/home_on.svg';
const assetRedemptions1 = 'assets/redeemed_on.svg';
const assetProfile1 = 'assets/profile_on.svg';
return Scaffold(
extendBody: true,body: PageStorage(
child: currentScreen,bucket: bucket,),bottomNavigationBar: BottomAppBar(
color: colorGreen,child: Container(
height: 45,child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,children: <Widget>[
MaterialButton(
minWidth: 5,onpressed: () {
setState(() {
currentScreen = DealActivity();
; // if user taps on this dashboard tab will be active
currentTab = 0;
});
},child: Column(
mainAxisAlignment: MainAxisAlignment.center,children: <Widget>[
Padding(
padding: EdgeInsets.all(1.0),child: currentTab == 0 ? SvgPicture.asset(assetHome1,color: Colors.white,width: 20,height: 20,semanticslabel: 'Home'):SvgPicture.asset(assetHome,semanticslabel: 'Home'),],MaterialButton(
minWidth: 5,onpressed: () async{
setState(() {
currentScreen =_email == "" ?RedemptionPage():FinalLoginPage(); // if user taps on this dashboard tab will be active
currentTab = 2;
});
SharedPreferences prefs =
await SharedPreferences.getInstance();
prefs.setInt('currentTab',currentTab);
},child: currentTab == 2 ? SvgPicture.asset(assetRedemptions1,semanticslabel: 'Redemptions'):SvgPicture.asset(assetRedemptions,semanticslabel: 'Redemptions'),onpressed: () {
setState(() {
currentScreen = _email == ""
? ProfilePage()
: ProfilePageUsers(); // if user taps on this dashboard tab will be active
currentTab = 3;
});
},child: currentTab == 3 ? SvgPicture.asset(assetProfile1,semanticslabel: 'Profile'):SvgPicture.asset(assetProfile,semanticslabel: 'Profile'),);
}
}
例如,如果我单击DealActivity()并从DealActivity移至另一页,则我希望底部导航停留在底部,并在我从DealActivity中从一页移至另一页时仍显示DealActivity图标处于活动状态。另外,如果位于FinalLoginPage()中,并且在我移至另一页面内,则底部导航应保持其图标处于活动状态。 ProfilePageUsers()也应如此。我真的很感激能帮助实现这一目标。
解决方法
您可以在下面复制粘贴运行完整代码
您可以使用软件包https://pub.dev/packages/persistent_bottom_nav_bar
在工作的演示中,您可以看到每个屏幕都有其自己的路线,并且在导航
工作演示
完整代码
import 'package:flutter/material.dart';
import 'package:persistent_bottom_nav_bar/persistent-tab-view.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Persistent Bottom Navigation Bar example project',theme: ThemeData(
primarySwatch: Colors.blue,),home: MainMenu(),initialRoute: '/',);
}
}
class MainMenu extends StatefulWidget {
MainMenu({Key key}) : super(key: key);
@override
_MainMenuState createState() => _MainMenuState();
}
class _MainMenuState extends State<MainMenu> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Sample Project"),body: Column(
mainAxisAlignment: MainAxisAlignment.center,children: <Widget>[
Center(
child: RaisedButton(
child: Text("Custom widget example"),onPressed: () => pushNewScreen(
context,screen: CustomWidgetExample(
menuScreenContext: context,SizedBox(height: 20.0),Center(
child: RaisedButton(
child: Text("Built-in styles example"),screen: ProvidedStylesExample(
menuScreenContext: context,],);
}
}
// ----------------------------------------- Provided Style ----------------------------------------- //
class ProvidedStylesExample extends StatefulWidget {
final BuildContext menuScreenContext;
ProvidedStylesExample({Key key,this.menuScreenContext}) : super(key: key);
@override
_ProvidedStylesExampleState createState() => _ProvidedStylesExampleState();
}
class _ProvidedStylesExampleState extends State<ProvidedStylesExample> {
PersistentTabController _controller;
bool _hideNavBar;
@override
void initState() {
super.initState();
_controller = PersistentTabController(initialIndex: 0);
_hideNavBar = false;
}
List<Widget> _buildScreens() {
return [
MainScreen(
menuScreenContext: widget.menuScreenContext,hideStatus: _hideNavBar,onScreenHideButtonPressed: () {
setState(() {
_hideNavBar = !_hideNavBar;
});
},MainScreen(
menuScreenContext: widget.menuScreenContext,];
}
List<PersistentBottomNavBarItem> _navBarsItems() {
return [
PersistentBottomNavBarItem(
icon: Icon(Icons.home),title: "Home",activeColor: Colors.blue,inactiveColor: Colors.grey,PersistentBottomNavBarItem(
icon: Icon(Icons.search),title: ("Search"),activeColor: Colors.teal,PersistentBottomNavBarItem(
icon: Icon(Icons.add),title: ("Add"),activeColor: Colors.blueAccent,activeContentColor: Colors.white,PersistentBottomNavBarItem(
icon: Icon(Icons.message),title: ("Messages"),activeColor: Colors.deepOrange,PersistentBottomNavBarItem(
icon: Icon(Icons.settings),title: ("Settings"),activeColor: Colors.indigo,];
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Navigation Bar Demo')),drawer: Drawer(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,children: <Widget>[
const Text('This is the Drawer'),body: PersistentTabView(
controller: _controller,screens: _buildScreens(),items: _navBarsItems(),confineInSafeArea: true,backgroundColor: Colors.white,handleAndroidBackButtonPress: true,resizeToAvoidBottomInset: true,stateManagement: true,hideNavigationBarWhenKeyboardShows: true,hideNavigationBar: _hideNavBar,margin: EdgeInsets.all(10.0),popActionScreens: PopActionScreensType.once,bottomScreenMargin: 0.0,// onWillPop: () async {
// await showDialog(
// context: context,// useSafeArea: true,// builder: (context) => Container(
// height: 50.0,// width: 50.0,// color: Colors.white,// child: RaisedButton(
// child: Text("Close"),// onPressed: () {
// Navigator.pop(context);
// },// ),// ),// );
// return false;
// },decoration: NavBarDecoration(
colorBehindNavBar: Colors.indigo,borderRadius: BorderRadius.circular(20.0)),popAllScreensOnTapOfSelectedTab: true,itemAnimationProperties: ItemAnimationProperties(
duration: Duration(milliseconds: 400),curve: Curves.ease,screenTransitionAnimation: ScreenTransitionAnimation(
animateTabTransition: true,duration: Duration(milliseconds: 200),navBarStyle:
NavBarStyle.style15,// Choose the nav bar style with this property
),);
}
}
// ----------------------------------------- Custom Style ----------------------------------------- //
class CustomNavBarWidget extends StatelessWidget {
final int selectedIndex;
final List<PersistentBottomNavBarItem> items;
final ValueChanged<int> onItemSelected;
CustomNavBarWidget({
Key key,this.selectedIndex,@required this.items,this.onItemSelected,});
Widget _buildItem(PersistentBottomNavBarItem item,bool isSelected) {
return Container(
alignment: Alignment.center,height: kBottomNavigationBarHeight,child: Column(
mainAxisAlignment: MainAxisAlignment.center,crossAxisAlignment: CrossAxisAlignment.center,mainAxisSize: MainAxisSize.min,children: <Widget>[
Flexible(
child: IconTheme(
data: IconThemeData(
size: 26.0,color: isSelected
? (item.activeContentColor == null
? item.activeColor
: item.activeContentColor)
: item.inactiveColor == null
? item.activeColor
: item.inactiveColor),child: item.icon,Padding(
padding: const EdgeInsets.only(top: 5.0),child: Material(
type: MaterialType.transparency,child: FittedBox(
child: Text(
item.title,style: TextStyle(
color: isSelected
? (item.activeContentColor == null
? item.activeColor
: item.activeContentColor)
: item.inactiveColor,fontWeight: FontWeight.w400,fontSize: item.titleFontSize),)),)
],);
}
@override
Widget build(BuildContext context) {
return Container(
color: Colors.white,child: Container(
width: double.infinity,child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,children: items.map((item) {
var index = items.indexOf(item);
return Flexible(
child: GestureDetector(
onTap: () {
this.onItemSelected(index);
},child: _buildItem(item,selectedIndex == index),);
}).toList(),);
}
}
class CustomWidgetExample extends StatefulWidget {
final BuildContext menuScreenContext;
CustomWidgetExample({Key key,this.menuScreenContext}) : super(key: key);
@override
_CustomWidgetExampleState createState() => _CustomWidgetExampleState();
}
class _CustomWidgetExampleState extends State<CustomWidgetExample> {
PersistentTabController _controller;
bool _hideNavBar;
@override
void initState() {
super.initState();
_controller = PersistentTabController(initialIndex: 0);
_hideNavBar = false;
}
List<Widget> _buildScreens() {
return [
MainScreen(
menuScreenContext: widget.menuScreenContext,itemCount: 5,customWidget: CustomNavBarWidget(
items: _navBarsItems(),onItemSelected: (index) {
setState(() {
_controller.index = index; // THIS IS CRITICAL!! Don't miss it!
});
},selectedIndex: _controller.index,navBarStyle:
NavBarStyle.custom,);
}
}
class MainScreen extends StatelessWidget {
final BuildContext menuScreenContext;
final Function onScreenHideButtonPressed;
final bool hideStatus;
const MainScreen(
{Key key,this.menuScreenContext,this.onScreenHideButtonPressed,this.hideStatus = false})
: super(key: key);
@override
Widget build(BuildContext context) {
return SingleChildScrollView(
child: SizedBox(
height: MediaQuery.of(context).size.height,width: MediaQuery.of(context).size.width,child: Scaffold(
backgroundColor: Colors.indigo,body: Column(
mainAxisAlignment: MainAxisAlignment.center,children: <Widget>[
Padding(
padding: const EdgeInsets.symmetric(
horizontal: 30.0,vertical: 20.0),child: TextField(
decoration: InputDecoration(hintText: "Test Text Field"),Center(
child: RaisedButton(
color: Colors.blue,onPressed: () {
pushNewScreenWithRouteSettings(context,settings: RouteSettings(name: '/home'),screen: MainScreen2(),pageTransitionAnimation:
PageTransitionAnimation.scaleRotate);
},child: Text(
"Go to Second Screen ->",style: TextStyle(color: Colors.white),Center(
child: RaisedButton(
color: Colors.deepOrange,onPressed: () {
showModalBottomSheet(
context: context,useRootNavigator: true,builder: (context) => Center(
child: RaisedButton(
onPressed: () {
Navigator.pop(context);
},color: Colors.blue,child: Text(
"Exit",);
},child: Text(
"Push bottom sheet on TOP of Nav Bar",useRootNavigator: false,child: Text(
"Push bottom sheet BEHIND the Nav Bar",Center(
child: RaisedButton(
color: Colors.lime,onPressed: () {
pushDynamicScreen(context,screen: SampleModalScreen(),withNavBar: true);
},child: Text(
"Push Dynamic/Modal Screen",Center(
child: RaisedButton(
color: Colors.purpleAccent,onPressed: () {
this.onScreenHideButtonPressed();
},child: Text(
this.hideStatus
? "Unhide Navigation Bar"
: "Hide Navigation Bar",Center(
child: RaisedButton(
color: Colors.red,onPressed: () {
Navigator.of(this.menuScreenContext).pop();
},child: Text(
"<- Main Menu",SizedBox(
height: 60.0,);
}
}
class MainScreen2 extends StatelessWidget {
const MainScreen2({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.teal,body: Container(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,children: <Widget>[
RaisedButton(
color: Colors.indigo,onPressed: () {
pushNewScreen(context,screen: MainScreen3());
},child: Text(
"Go to Third Screen",RaisedButton(
color: Colors.indigo,onPressed: () {
Navigator.pop(context);
},child: Text(
"Go Back to First Screen",);
}
}
class MainScreen3 extends StatelessWidget {
const MainScreen3({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.deepOrangeAccent,body: Container(
child: Center(
child: RaisedButton(
color: Colors.blue,onPressed: () {
Navigator.pop(context);
},child: Text(
"Go Back to Second Screen",);
}
}
class SampleModalScreen extends ModalRoute<void> {
SampleModalScreen();
@override
Duration get transitionDuration => Duration(milliseconds: 500);
@override
bool get opaque => false;
@override
bool get barrierDismissible => false;
@override
Color get barrierColor => Colors.black.withOpacity(0.5);
@override
String get barrierLabel => null;
@override
bool get maintainState => true;
@override
Widget buildPage(
BuildContext context,Animation<double> animation,Animation<double> secondaryAnimation,) {
// This makes sure that text and other content follows the material style
return Material(
type: MaterialType.transparency,// make sure that the overlay content is not cut off
child: SafeArea(
child: _buildOverlayContent(context),);
}
Widget _buildOverlayContent(BuildContext context) {
return Container(
height: MediaQuery.of(context).size.height * 0.3,width: MediaQuery.of(context).size.width * 0.3,margin: EdgeInsets.all(30.0),padding: EdgeInsets.symmetric(horizontal: 30.0),color: Colors.amber,children: <Widget>[
Text(
"This is a modal screen",textAlign: TextAlign.center,style: TextStyle(
color: Colors.black,fontSize: 26.0,Center(
child: RaisedButton(
color: Colors.blue,onPressed: () {
Navigator.pop(context);
},child: Text(
"Return",);
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。