我使用ListViews
在TabBarView
内进行了两次TabController
渲染。
如何在每个ListView
之间保留状态(缺少更好的词),以便:1)小部件不重建,以及2.)在标签之间记住ListView
位置
class AppState extends State<App> with SingleTickerProviderStateMixin {
TabController _tabController;
@override
void initState() {
super.initState();
_tabController = new TabController(
vsync: this,
length: _allPages.length,
);
}
@override
void dispose() {
_tabController.dispose();
super.dispose();
}
Widget _buildScaffold(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('headlines'),
bottom: new TabBar(
controller: _tabController,
isScrollable: true,
tabs: _allPages
.map((_Page page) => new Tab(text: page.country))
.toList()),
),
body: new TabBarView(
controller: _tabController,
children: _allPages.map((_Page page) {
return new SafeArea(
top: false,
bottom: false,
child: new Container(
key: new ObjectKey(page.country),
child: new Newsfeed(country: page.country),
),
);
}).toList()),
);
}
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'news app',
home: _buildScaffold(context),
);
}
}
答案 0 :(得分:16)
如果要将屏幕状态保留在TabBarView
中,可以在State类中使用名为AutomaticKeepAliveClientMixin
的mixin类。
此后,您必须覆盖wantKeepAlive
方法并返回true
。
我在这里写了一篇关于此的帖子:https://medium.com/@diegoveloper/flutter-persistent-tab-bars-a26220d322bc
答案 1 :(得分:6)
长话短说,请为您的ListView或其中一个祖先使用PageStorageKey(),在您的情况下使用Container小部件:
child: new Container(
key: new PageStorageKey(page.country),
child: new Newsfeed(country: page.country),
),
详情请见:
答案 2 :(得分:6)
在我们的国家使用mixin
和AutomaticKeepAliveClientMixin
。
并实施:bool get wantKeepAlive => true;
class ResidentListScreen extends StatefulWidget {
@override
_ResidentListScreenState createState() => _ResidentListScreenState();
}
class _ResidentListScreenState extends State<ResidentListScreen> with
AutomaticKeepAliveClientMixin<ResidentListScreen>{
@override
bool get wantKeepAlive => true;
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
}
}
答案 3 :(得分:0)
尝试在带有偏移量的堆栈中包含子视图。它帮助我保存了我的底栏导航状态。
答案 4 :(得分:0)
我遵循了这些建议,但是这些建议没有用,所以我创建了自己的建议。到目前为止,效果很好。
我的解决方案。
基本上只是一个水平ListView,其中禁用了滚动并且元素上的最大宽度。我正在使用一个非常繁重的标签(Google地图)对其进行测试,并且效果很好。
包含上述元素的列表视图:
Widget body(BuildContext context) {
final double width = MediaQuery.of(context).size.width;
return ListView(
controller: scrollController,
scrollDirection: Axis.horizontal,
physics: NeverScrollableScrollPhysics(),
children: <Widget>[
Container(width: width, child: TabLiveEvents()),
Container(width: width, child: TabEvents()),
],
);
}
标签栏布局。
Widget bottomNavbar(BuildContext context) {
return BottomNavigationBar(
items: [
BottomNavigationBarItem(
icon: Icon(Icons.chat_bubble),
title: Text(Translation.tabMeetupText)),
BottomNavigationBarItem(
icon: Icon(Icons.list), title: Text(Translation.tabEventslist)),
],
currentIndex: _selectedIndex,
fixedColor: Theme.of(context).accentColor,
onTap: _onItemTapped,
);
}
通过点击项目切换列表视图时。
void _onItemTapped(int index) {
setState(() {
_selectedIndex = index;
});
double width = MediaQuery.of(context).size.width * index;
scrollController.jumpTo(width);
}
主窗口小部件
@override
Widget build(BuildContext context) {
return DefaultTabController(
length: 2,
child: Scaffold(
appBar: appBar(),
bottomNavigationBar: bottomNavbar(context),
body: body(context),
),
);
}