это первый вопрос, который я задаю в StackOverflow, и я надеюсь, что предоставлю все необходимое для правильного ответа.
Я создаю клон Instagram, и я хочу использовать CupertinoTabBar для mimi c the поведение приложения Instagram.
Поведение в Instagram: Gif
Основная проблема на данный момент заключается в том, что я хочу отобразить полностраничный диалог для создания сообщения, нажав значок на Панель навигации. Обычно я бы использовал такой код:
Navigator.of(
context,
rootNavigator: true,
).push<...>(
SlidePageTransitionBuilder<...>(
builder: ...,
transitionCurve: routeCurve,
transitionDuration: routeDuration,
),
);
Но, к сожалению, я не могу поместить этот Navigator.pu sh на нажатую иконку панели, поскольку он ожидает возвращаемого типа виджета, который Я не знаю, как обеспечить ожидаемое поведение.
Чья-то помощь очень ценится. Пожалуйста, дайте мне знать, если вам нужна дополнительная информация.
Пример кода проекта:
Git Hub Repo
main.dart:
import 'package:flutter/material.dart';
import 'cupertino_home_scaffold.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: HomePage(),
);
}
}
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
TabItem _currentTab = TabItem.timeline;
final Map<TabItem, GlobalKey<NavigatorState>> navigatorKeys = {
TabItem.timeline: GlobalKey<NavigatorState>(),
TabItem.map: GlobalKey<NavigatorState>(),
TabItem.share: GlobalKey<NavigatorState>(),
TabItem.account: GlobalKey<NavigatorState>(),
};
Map<TabItem, WidgetBuilder> get widgetBuilders {
return {
TabItem.timeline: (_) => SomePage(),
TabItem.map: (_) => SomePage(),
TabItem.share: (context) =>
PostPage(), //Should be displayed with Navigator.push...,
TabItem.account: (_) => SomePage(),
};
}
void _select(TabItem tabItem) {
if (tabItem == _currentTab) {
navigatorKeys[tabItem].currentState.popUntil((route) => route.isFirst);
} else {
setState(() {
_currentTab = tabItem;
});
}
}
@override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () async =>
!await navigatorKeys[_currentTab].currentState.maybePop(),
child: CupertinoHomeScaffold(
navigatorKeys: navigatorKeys,
currentTab: _currentTab,
onSelectTab: _select,
widgetBuilders: widgetBuilders,
),
);
}
}
cupertino_home_scaffold.dart
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class CupertinoHomeScaffold extends StatelessWidget {
const CupertinoHomeScaffold({
Key key,
@required this.currentTab,
@required this.onSelectTab,
@required this.widgetBuilders,
@required this.navigatorKeys,
}) : super(key: key);
final TabItem currentTab;
final ValueChanged<TabItem> onSelectTab;
final Map<TabItem, WidgetBuilder> widgetBuilders;
final Map<TabItem, GlobalKey<NavigatorState>> navigatorKeys;
@override
Widget build(BuildContext context) {
return CupertinoTabScaffold(
tabBar: CupertinoTabBar(
items: [
_buildItem(TabItem.timeline),
_buildItem(TabItem.map),
_buildItem(TabItem.share),
_buildItem(TabItem.account),
],
onTap: (index) => onSelectTab(TabItem.values[index]),
),
tabBuilder: (context, index) {
final item = TabItem.values[index];
print(item);
return CupertinoTabView(
navigatorKey: navigatorKeys[item],
builder: (context) => widgetBuilders[item](context),
);
},
);
}
BottomNavigationBarItem _buildItem(TabItem tabItem) {
final itemData = TabItemData.allTabs[tabItem];
final color = currentTab == tabItem ? Colors.black : Colors.grey;
return BottomNavigationBarItem(
icon: Icon(
itemData.icon,
color: color,
),
title: Text(
itemData.title,
style: TextStyle(color: color),
),
);
}
}
enum TabItem { timeline, map, share, account }
class TabItemData {
const TabItemData({@required this.title, @required this.icon});
final String title;
final IconData icon;
static const Map<TabItem, TabItemData> allTabs = {
TabItem.timeline: TabItemData(title: 'Home', icon: Icons.home),
TabItem.map: TabItemData(title: 'Map', icon: Icons.pin_drop),
TabItem.share: TabItemData(title: 'Share', icon: Icons.add_circle_outline),
TabItem.account: TabItemData(title: 'Account', icon: Icons.person),
};
}