Со ссылкой на статью Ханса Мюллера о создании эффекта затухания и использовании нижней панели навигации в Flutter, приведенный ниже код не переключает экраны при нажатии. Он остается на том же экране, то есть на домашнем экране, даже после того, как я нажимаю на различные элементы нижней панели навигации.
Ниже приведен фрагмент моего кода, который в основном является копией кода в статье. Я не могу понять, почему переход экрана не работает, когда я нажимаю на кнопки панели навигации.
class NavigationRouterScreen extends StatefulWidget {
@override
_NavigationRouterScreenState createState() => _NavigationRouterScreenState();
}
class _NavigationRouterScreenState extends State<NavigationRouterScreen> with TickerProviderStateMixin<NavigationRouterScreen> {
List<Key> _destinationKeys;
List<AnimationController> _faders;
AnimationController _hide;
int _currentIndex = 0;
@override
void initState() {
super.initState();
_faders = allDestinations.map<AnimationController>((Destination destination) {
return AnimationController(vsync: this, duration: Duration(milliseconds: 200));
}).toList();
_faders[_currentIndex].value = 1.0;
_destinationKeys = List<Key>.generate(allDestinations.length, (int index) => GlobalKey()).toList();
_hide = AnimationController(vsync: this, duration: kThemeAnimationDuration);
}
@override
void dispose() {
for (AnimationController controller in _faders)
controller.dispose();
_hide.dispose();
super.dispose();
}
bool _handleScrollNotification(ScrollNotification notification) {
if (notification.depth == 0) {
if (notification is UserScrollNotification) {
final UserScrollNotification userScroll = notification;
switch (userScroll.direction) {
case ScrollDirection.forward:
_hide.forward();
break;
case ScrollDirection.reverse:
_hide.reverse();
break;
case ScrollDirection.idle:
break;
}
}
}
return false;
}
Color colorByIndex(int index) {
return index == _currentIndex ? Color(0xFF323255) : Colors.grey;
}
List<Widget> allChildren() {
var listofitems = allDestinations.map((Destination destination) {
final Widget view = FadeTransition(
opacity: _faders[destination.index].drive(CurveTween(curve: Curves.fastOutSlowIn)),
child: KeyedSubtree(
key: _destinationKeys[destination.index],
child: DestinationView(
destination: destination,
onNavigation: () {
_hide.forward();
},
),
),
);
if (destination.index == _currentIndex) {
_faders[destination.index].forward();
return view;
} else {
_faders[destination.index].reverse();
if (_faders[destination.index].isAnimating) {
return IgnorePointer(child: view);
}
return Offstage(child: view);
}
}).toList();
return listofitems;
}
@override
Widget build(BuildContext context) {
return NotificationListener(
onNotification: _handleScrollNotification,
child: Scaffold(
bottomNavigationBar: ClipRect(
child: SizeTransition(
sizeFactor: _hide,
axisAlignment: -1.0,
child: BottomNavigationBar(
type: BottomNavigationBarType.fixed,
currentIndex: _currentIndex,
onTap: (int index) {
setState(() {
_currentIndex = index;
});
},
items: allDestinations.map((Destination destination) {
return BottomNavigationBarItem(
icon: SvgPicture.asset(
destination.iconPath,
height: 24.0,
width: 24.0,
color: colorByIndex(destination.index),
),
title: Text(destination.title,
style: TextStyle(
fontSize: 11.0,
color: colorByIndex(destination.index),
),
),
);
}).toList(),
),
),
),
body: SafeArea(
top: false,
child: Stack(
fit: StackFit.expand,
children: allChildren(),
),
),
),
);
}
}
class DestinationView extends StatefulWidget {
const DestinationView({ Key key, this.destination, this.onNavigation }) : super(key: key);
final Destination destination;
final VoidCallback onNavigation;
@override
_DestinationViewState createState() => _DestinationViewState();
}
class _DestinationViewState extends State<DestinationView> {
Route _registerRoutesWithParameters(RouteSettings settings) {
return MaterialPageRoute(
settings: settings,
builder: (context) {
switch(settings.name) {
case RouteConstants.home:
print(settings.name);
return HomeScreen(destination: widget.destination);
case RouteConstants.stats:
return StatsScreen(destination: widget.destination);
case RouteConstants.profile:
return ProfileScreen(destination: widget.destination);
default:
return HomeScreen(destination: widget.destination);
}
},
);
}
@override
Widget build(BuildContext context) {
return Navigator(
observers: <NavigatorObserver>[
ViewNavigatorObserver(widget.onNavigation),
],
onGenerateRoute: _registerRoutesWithParameters,
);
}
}
class ViewNavigatorObserver extends NavigatorObserver {
ViewNavigatorObserver(this.onNavigation);
final VoidCallback onNavigation;
void didPop(Route<dynamic> route, Route<dynamic> previousRoute) {
onNavigation();
}
void didPush(Route<dynamic> route, Route<dynamic> previousRoute) {
onNavigation();
}
}