【发布时间】:2021-01-19 10:55:19
【问题描述】:
请查看此Demo app。它有一个 Cupertino 底部导航栏和产品页面上的两个选项卡。我在下面提供了代码 sn-ps(注意:代码主要改编自官方文档)。
我的问题
当点击任何 BottomNavigationBarItem 项目(无论是产品、搜索还是购物车)时,我希望将产品页面上的选项卡控制器的索引重置为 0,并在该页面上调用 setState。我如何做到这一点?
我正在努力实现的目标
- 在“产品”页面上,如果我选择右侧选项卡(选项卡索引 = 1),我还希望能够通过点击底部导航中的产品导航回左侧选项卡(选项卡索引 = 0)。
- 在产品页面上,如果我选择右标签(标签索引 = 1),然后导航到不同的页面(搜索页面或购物车页面),然后返回产品页面,我想要左标签(标签index = 0) 默认显示。
希望这是有道理的。谢谢!
(免责声明:我是开发和 Stackoverflow 的新手,所以我希望我的问题措辞正确。我一定会在收到相关反馈时对其进行修改)。
main.dart
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'products_page.dart';
import 'search_page.dart';
import 'cart_page.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Demo app',
theme: ThemeData(primarySwatch: Colors.blue),
home: HomePage(),
);
}
}
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return CupertinoTabScaffold(
tabBar: CupertinoTabBar(
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.home),
title: Text('Products'),
),
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.search),
title: Text('Search'),
),
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.shopping_cart),
title: Text('Cart'),
),
],
),
tabBuilder: (context, index) {
CupertinoTabView returnValue;
switch (index) {
case 0:
returnValue = CupertinoTabView(builder: (context) {
return CupertinoPageScaffold(
child: ProductsPage(),
);
});
break;
case 1:
returnValue = CupertinoTabView(builder: (context) {
return CupertinoPageScaffold(
child: SearchPage(),
);
});
break;
case 2:
returnValue = CupertinoTabView(builder: (context) {
return CupertinoPageScaffold(
child: CartPage(),
);
});
break;
}
return returnValue;
},
);
}
}
products_page.dart
import 'package:flutter/material.dart';
class ProductsPage extends StatefulWidget {
@override
_ProductsPageState createState() => _ProductsPageState();
}
class _ProductsPageState extends State<ProductsPage> with SingleTickerProviderStateMixin {
TabController _tabController;
@override
void initState() {
super.initState();
_tabController = TabController(vsync: this, length: 2);
}
@override
void dispose() {
_tabController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: NestedScrollView(
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
return <Widget>[
SliverAppBar(
floating: false,
pinned: true,
flexibleSpace: FlexibleSpaceBar(
centerTitle: true,
title: Text('Products'),
),
),
SliverPersistentHeader(
delegate: _SliverAppBarDelegate(
TabBar(
controller: _tabController,
labelColor: Colors.black87,
unselectedLabelColor: Colors.grey,
tabs: [
Tab(text: 'LEFT'),
Tab(text: 'RIGHT'),
],
// controller:,
),
),
pinned: true,
),
];
},
body: TabBarView(
controller: _tabController,
children: <Widget>[
Center(child: Text('This is the left tab', style: TextStyle(fontSize: 30))),
Center(child: Text('This is the right tab', style: TextStyle(fontSize: 30))),
],
),
),
);
}
}
class _SliverAppBarDelegate extends SliverPersistentHeaderDelegate {
_SliverAppBarDelegate(this._tabBar);
final TabBar _tabBar;
@override
double get minExtent => _tabBar.preferredSize.height;
@override
double get maxExtent => _tabBar.preferredSize.height;
@override
Widget build(BuildContext context, double shrinkOffset, bool overlapsContent) {
return Container(
color: Colors.white,
child: _tabBar,
);
}
@override
bool shouldRebuild(_SliverAppBarDelegate oldDelegate) {
return false;
}
}
【问题讨论】:
-
请添加一些代码sn-p以便更清楚
-
你这样做了吗?
-
@Andrej 该教程展示了如何使用 tabController 设置选项卡。但它没有为上述场景提供任何解决方案。