我在Flutter中的BottomNavigationBar出现问题。如果要更改标签,我想让页面保持活动状态。
这是我的实现
底部导航
class Home extends StatefulWidget { @override State<StatefulWidget> createState() { return _HomeState(); } } class _HomeState extends State<Home> { int _currentIndex = 0; List<Widget> _children; final Key keyOne = PageStorageKey("IndexTabWidget"); @override void initState() { _children = [ IndexTabWidget(key: keyOne), PlaceholderWidget(Colors.green), NewsListWidget(), ShopsTabWidget(), PlaceholderWidget(Colors.blue), ]; super.initState(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(MyApp.appName), textTheme: Theme.of(context).textTheme.apply( bodyColor: Colors.black, displayColor: Colors.blue, ), ), body: _children[_currentIndex], bottomNavigationBar: BottomNavigationBar( onTap: onTabTapped, key: IHGApp.globalKey, fixedColor: Colors.green, type: BottomNavigationBarType.fixed, currentIndex: _currentIndex, items: [ BottomNavigationBarItem( icon: Icon(Icons.home), title: Container(height: 0.0), ), BottomNavigationBarItem( icon: Icon(Icons.message), title: Container(height: 0.0), ), BottomNavigationBarItem( icon: Icon(Icons.settings), title: Container(height: 0.0), ), BottomNavigationBarItem( icon: Icon(Icons.perm_contact_calendar), title: Container(height: 0.0), ), BottomNavigationBarItem( icon: Icon(Icons.business), title: Container(height: 0.0), ), ], ), ); } void onTabTapped(int index) { setState(() { _currentIndex = index; }); } Column buildButtonColumn(IconData icon) { Color color = Theme.of(context).primaryColor; return Column( mainAxisSize: MainAxisSize.min, mainAxisAlignment: MainAxisAlignment.center, children: [ Icon(icon, color: color), ], ); } }
这是我的索引页面(第一个标签):
class IndexTabWidget extends StatefulWidget { IndexTabWidget({Key key}) : super(key: key); @override State<StatefulWidget> createState() { return new IndexTabState(); } } class IndexTabState extends State<IndexTabWidget> with AutomaticKeepAliveClientMixin { List<News> news = List(); FirestoreNewsRepo newsFirestore = FirestoreNewsRepo(); @override Widget build(BuildContext context) { return Material( color: Colors.white, child: new Container( child: new SingleChildScrollView( child: new ConstrainedBox( constraints: new BoxConstraints(), child: new Column( children: <Widget>[ HeaderWidget( CachedNetworkImageProvider( 'https://static1.fashionbeans.com/wp-content/uploads/2018/04/50-barbershop-top-savill.jpg', ), "", ), AboutUsWidget(), Padding( padding: const EdgeInsets.all(16.0), child: SectionTitleWidget(title: StringStorage.salonsTitle), ), StreamBuilder( stream: newsFirestore.observeNews(), builder: (context, snapshot) { if (!snapshot.hasData) { return CircularProgressIndicator(); } else { news = snapshot.data; return Column( children: <Widget>[ ShopItemWidget( AssetImage('assets/images/picture.png'), news[0].title, news[0], ), ShopItemWidget( AssetImage('assets/images/picture1.png'), news[1].title, news[1], ) ], ); } }, ), Padding( padding: const EdgeInsets.only( left: 16.0, right: 16.0, bottom: 16.0), child: SectionTitleWidget(title: StringStorage.galleryTitle), ), GalleryCategoryCarouselWidget(), ], ), ), ), ), ); } @override bool get wantKeepAlive => true; }
因此,如果我从索引选项卡切换到其他任何选项卡,然后再回到索引选项卡,则索引选项卡将始终重建。我对其进行了调试,发现在选项卡开关上总是会调用build函数。
你们能帮我解决这个问题吗?
非常感谢Albo
以前的答案都没有为我解决。
切换选项卡时使页面保持活动状态的解决方案是将页面包装在 IndexedStack中 。
class Tabbar extends StatefulWidget { Tabbar({this.screens}); static const Tag = "Tabbar"; final List<Widget> screens; @override State<StatefulWidget> createState() { return _TabbarState(); } } class _TabbarState extends State<Tabbar> { int _currentIndex = 0; Widget currentScreen; @override Widget build(BuildContext context) { var _l10n = PackedLocalizations.of(context); return Scaffold( body: IndexedStack( index: _currentIndex, children: widget.screens, ), bottomNavigationBar: BottomNavigationBar( fixedColor: Colors.black, type: BottomNavigationBarType.fixed, onTap: onTabTapped, currentIndex: _currentIndex, items: [ BottomNavigationBarItem( icon: new Icon(Icons.format_list_bulleted), title: new Text(_l10n.tripsTitle), ), BottomNavigationBarItem( icon: new Icon(Icons.settings), title: new Text(_l10n.settingsTitle), ) ], ), ); } void onTabTapped(int index) { setState(() { _currentIndex = index; }); } }