我为个人项目创建了一个入门工具包。
一切正常,但是我有个提示,无法在抽屉中突出显示当前选中的项目。
下面是我的代码!
class _MdDrawerState extends State<MdDrawer>
with SingleTickerProviderStateMixin<MdDrawer> {
final _animationDuration = const Duration(milliseconds: 350);
AnimationController _animationController;
Stream<bool> isDrawerOpenStream;
StreamController<bool> isDrawerOpenStreamController;
StreamSink<bool> isDrawerOpenSink;
.....
@override
void dispose() {
_animationController.dispose();
isDrawerOpenStreamController.close();
isDrawerOpenSink.close();
super.dispose();
}
void onIconPressed() {
final animationStatus = _animationController.status;
final isAnimationCompleted = animationStatus == AnimationStatus.completed;
.....
}
@override
Widget build(BuildContext context) {
final screenWidth = MediaQuery.of(context).size.width;
return StreamBuilder<bool>(
initialData: false,
stream: isDrawerOpenStream,
builder: (context, isLeftDrawerOpenedAsync) {
return AnimatedPositioned(
duration: _animationDuration,
top: 0,
bottom: 0,
left: isLeftDrawerOpenedAsync.data ? 0 : -screenWidth,
right: isLeftDrawerOpenedAsync.data ? 0 : screenWidth - 45,
child: Row(
children: <Widget>[
Expanded(
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 20),
color: Theme.of(context).backgroundColor,
child: ListView(
children: <Widget>[
Column(
children: <Widget>[
SizedBox(
height: 30,
),
ListTile(
title: Text('First - Last',
style: Theme.of(context).textTheme.headline),
subtitle: Text('something@gmail.com',
style: Theme.of(context).textTheme.subhead),
leading: CircleAvatar(
child: Icon(
Icons.perm_identity,
color: Theme.of(context).iconTheme.color,
),
radius: 40,
),
),
Divider(
height: 30,
),
MdNavItem(
icon: Icons.home,
title: 'Home',
onTap: () {
onIconPressed();
BlocProvider.of<MdNavBloc>(context)
.add(NavigationEvents.HomeClickedEvent);
},
),
MdNavItem(
icon: Icons.account_box,
title: 'Account',
onTap: () {
onIconPressed();
BlocProvider.of<MdNavBloc>(context)
.add(NavigationEvents.AccountClickedEvent);
},
),
MdNavItem(
icon: Icons.shopping_basket,
title: 'Orders',
onTap: () {
onIconPressed();
BlocProvider.of<MdNavBloc>(context)
.add(NavigationEvents.OrderClickedEvent);
},
),
MdNavItem(
icon: Icons.card_giftcard,
title: 'Wishlist',
onTap: () {
onIconPressed();
BlocProvider.of<MdNavBloc>(context)
.add(NavigationEvents.WishlistClickedEvent);
},
),
Divider(
height: 30,
),
MdNavItem(
icon: Icons.settings,
title: 'Settings',
onTap: () {
onIconPressed();
BlocProvider.of<MdNavBloc>(context)
.add(NavigationEvents.SettingsClickedEvent);
},
),
MdNavItem(
icon: Icons.exit_to_app,
title: 'Logout',
),
Divider(
height: 45,
),
],
),
],
),
),
),
......
],
),
);
},
);
}
}
还有MdNavItem类
class MdNavItem extends StatelessWidget {
final IconData icon;
final String title;
final Function onTap;
const MdNavItem({this.icon, this.title, this.onTap});
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: onTap,
child: Padding(
padding: const EdgeInsets.all(16),
child: Container(
color: Theme.of(context).backgroundColor,
child: Row(
children: <Widget>[
Icon(
icon,
size: 25,
color: Theme.of(context).iconTheme.color,
),
SizedBox(
width: 20,
),
Text(
title,
style: Theme.of(context).textTheme.headline,
),
],
),
),
),
);
}
}
答案 0 :(得分:0)
编辑:
第一种方法:
将此代码添加到您的抽屉中:
class _MdDrawerState extends State<MdDrawer>
with SingleTickerProviderStateMixin<MdDrawer> {
final _animationDuration = const Duration(milliseconds: 350);
AnimationController _animationController;
Stream<bool> isDrawerOpenStream;
StreamController<bool> isDrawerOpenStreamController;
StreamSink<bool> isDrawerOpenSink;
final List<bool> isTaped = [true, false, false, false, false]; // the first is true because when the app
//launch the home needs to be in red(or the
//color you choose)
void changeHighlight(int index){
for(int indexTap = 0; indexTap < isTaped.length; indexTap++) {
if (indexTap == index) {
isTaped[index] = true; //used to change the value of the bool list
} else {
isTaped[indexTap] = false;
}
}
}
.....
@override
void dispose() {
_animationController.dispose();
isDrawerOpenStreamController.close();
isDrawerOpenSink.close();
super.dispose();
}
void onIconPressed() {
final animationStatus = _animationController.status;
final isAnimationCompleted = animationStatus == AnimationStatus.completed;
.....
}
@override
Widget build(BuildContext context) {
final screenWidth = MediaQuery.of(context).size.width;
return StreamBuilder<bool>(
initialData: false,
stream: isDrawerOpenStream,
builder: (context, isLeftDrawerOpenedAsync) {
return AnimatedPositioned(
duration: _animationDuration,
top: 0,
bottom: 0,
left: isLeftDrawerOpenedAsync.data ? 0 : -screenWidth,
right: isLeftDrawerOpenedAsync.data ? 0 : screenWidth - 45,
child: Row(
children: <Widget>[
Expanded(
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 20),
color: Theme.of(context).backgroundColor,
child: ListView(
children: <Widget>[
Column(
children: <Widget>[
SizedBox(
height: 30,
),
ListTile(
title: Text('First - Last',
style: Theme.of(context).textTheme.headline),
subtitle: Text('something@gmail.com',
style: Theme.of(context).textTheme.subhead),
leading: CircleAvatar(
child: Icon(
Icons.perm_identity,
color: Theme.of(context).iconTheme.color,
),
radius: 40,
),
),
Divider(
height: 30,
),
MdNavItem(
wasTaped: isTaped[0],
icon: Icons.home,
title: 'Home',
onTap: () {
onIconPressed();
BlocProvider.of<MdNavBloc>(context)
.add(NavigationEvents.HomeClickedEvent);
changeHighlight(0);
},
),
MdNavItem(
wasTaped: isTaped[1],
icon: Icons.account_box,
title: 'Account',
onTap: () {
onIconPressed();
BlocProvider.of<MdNavBloc>(context)
.add(NavigationEvents.AccountClickedEvent);
changeHighlight(1);
},
),
MdNavItem(
wasTaped: isTaped[2],
icon: Icons.shopping_basket,
title: 'Orders',
onTap: () {
onIconPressed();
BlocProvider.of<MdNavBloc>(context)
.add(NavigationEvents.OrderClickedEvent);
changeHighlight(2);
},
),
MdNavItem(
wasTaped: isTaped[3],
icon: Icons.card_giftcard,
title: 'Wishlist',
onTap: () {
onIconPressed();
BlocProvider.of<MdNavBloc>(context)
.add(NavigationEvents.WishlistClickedEvent);
changeHighlight(3);
},
),
Divider(
height: 30,
),
MdNavItem(
wasTaped: isTaped[4],
icon: Icons.settings,
title: 'Settings',
onTap: () {
onIconPressed();
BlocProvider.of<MdNavBloc>(context)
.add(NavigationEvents.SettingsClickedEvent);
changeHighlight(4);
},
),
MdNavItem(
icon: Icons.exit_to_app,
title: 'Logout',
),
Divider(
height: 45,
),
],
),
],
),
),
),
......
],
),
);
},
);
}
}
然后将其发送到您的MdNavItem:
class MdNavItem extends StatelessWidget {
final IconData icon;
final String title;
final Function onTap;
final bool wasTaped; //receiving the bool value (if was taped or not)
const MdNavItem({this.icon, this.title, this.onTap, this.wasTaped});
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: onTap,
child: Padding(
padding: const EdgeInsets.all(16),
child: Container(
color: Theme.of(context).backgroundColor,
child: Row(
children: <Widget>[
Icon(
icon,
size: 25,
color: wasTaped ? Colors.red : Theme.of(context).iconTheme.color, //the condition to change the color
),
SizedBox(
width: 20,
),
Text(
title,
style: wasTaped ? TextStyle(
color: Colors.red,
) : Theme.of(context).textTheme.headline,
),
],
),
),
),
);
}
}
旧答案,第二种方式:
放置PageView的第一个屏幕:
class FirstScreen extends StatelessWidget {
final PageController pageController = PageController(initialPage: 0);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Kit App'),
),
drawer: CustomDrawer(
pageController: pageController,
),
body: PageView(
controller: pageController,
physics: NeverScrollableScrollPhysics(), //to prevent scroll
children: <Widget>[
HomeScreen(),
AccountScreen(), //your pages
OrdersScreen(),
WishListScreen(),
],
),
);
}
}
CustomDrawer:
class CustomDrawer extends StatelessWidget {
CustomDrawer({@required this.pageController});
final PageController pageController;
@override
Widget build(BuildContext context) {
return Drawer(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 20),
child: Column(
children: <Widget>[
DrawerItem(
onTap: (){
Navigator.pop(context); //to close the drawer
pageController.jumpToPage(0);
},
leading: Icons.home,
title: 'Home',
index: 0,
controller: pageController,
),
DrawerItem(
onTap: (){
Navigator.pop(context);
pageController.jumpToPage(1);
},
leading: Icons.account_box,
title: 'Account',
index: 1,
controller: pageController,
),
DrawerItem(
onTap: (){
Navigator.pop(context);
pageController.jumpToPage(2);
},
leading: Icons.shopping_cart,
title: 'Orders',
index: 2,
controller: pageController,
),
DrawerItem(
onTap: (){
Navigator.pop(context);
pageController.jumpToPage(3);
},
leading: Icons.card_travel,
title: 'Wishlist',
index: 3,
controller: pageController,
),
],
),
),
);
}
}
和DrawerItem,放置更改项目颜色的条件:
class DrawerItem extends StatelessWidget {
DrawerItem({
@required this.onTap,
@required this.leading,
@required this.title,
@required this.index,
@required this.controller,
});
final VoidCallback onTap;
final IconData leading;
final String title;
final int index;
final PageController controller;
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: onTap,
child: ListTile(
leading: Icon(
leading,
color: controller.page.round() == index ? Colors.red : Colors.grey,
),
title: Text(
title,
style: TextStyle(
color: controller.page.round() == index ? Colors.red : Colors.grey,
),
),
),
);
}
}
现在,您只需要在代码中实现它即可。