Flutter tabsView和NestedScrollView滚动问题
我有一个“ NestedScrollView”,其中包含多个“
TabView”小部件,并且每个选项卡都有一个列表生成器。问题是,当我滚动浏览特定选项卡中的一个列表时,滚动位置会影响其他选项卡中的所有其他列表。
即使我确实将“ ScrollController”添加到每个listview(在选项卡中),选项卡滚动中的listBuilder也与“
NestedScrollView”分开,这是示例代码:
import 'package:flutter/material.dart';void main() => runApp(
MaterialApp(
home: MyApp()
,
)
);
class MyApp extends StatefulWidget{
MyAppState createState() => MyAppState();
}
class MyAppState extends State<MyApp> with SingleTickerProviderStateMixin {
TabController tabController;
Widget _tabBarView;
@override
void initState() {
super.initState();
tabController = TabController(length: 2, vsync: this,);
_tabBarView = TabBarView(
children: [
DemoTab(),
DemoTab(),
]);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: NestedScrollView(
controller: ScrollController(keepScrollOffset: true),
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
return <Widget>[
SliverList(
delegate: SliverChildListDelegate(
[
Container(height: 300, color: Colors.blue)
]
),
),
];
},
body: DefaultTabController(
length: 2,
child: Column(
children: <Widget>[
Expanded(
child: Container(
child: _tabBarView
),
),
],
),
)
),
);
}
}
class DemoTab extends StatefulWidget{
DemoTabState createState() => DemoTabState();
}
class DemoTabState extends State<DemoTab> with AutomaticKeepAliveClientMixin<DemoTab>{
@override
// TODO: implement wantKeepAlive
bool get wantKeepAlive => true;
@override
Widget build(BuildContext context) {
return ListView.builder(
key: UniqueKey(),
itemBuilder: (b, i) {
return Container(
height: 50,
color: Colors.green,
margin: EdgeInsets.only(bottom: 3),
child: Text(i.toString(),),
);
}, itemCount: 30,) ;
}
}
回答:
3天后,我发现这是解决此问题的最佳方法,但仍需要更多改进,因为sliver标头扩展和收缩太快,您可以改进代码,并与我们分享
import 'package:flutter/material.dart';void main() => runApp(MaterialApp(
home: MyApp(),
));
class MyApp extends StatefulWidget {
MyAppState createState() => MyAppState();
}
class MyAppState extends State<MyApp> with SingleTickerProviderStateMixin {
TabController tabController;
Widget _tabBarView;
var scrollController = ScrollController();
@override
void initState() {
super.initState();
tabController = TabController(
length: 2,
vsync: this,
);
_tabBarView = TabBarView(children: [
DemoTab(parentController : scrollController),
DemoTab(parentController : scrollController),
]);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: NestedScrollView(
controller: scrollController,
physics: ScrollPhysics(parent: PageScrollPhysics()),
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
return <Widget>[
SliverList(
delegate: SliverChildListDelegate(
[Container(height: 300, color: Colors.blue)]),
),
];
},
body: DefaultTabController(
length: 2,
child: Column(
children: <Widget>[
Container(
child: TabBar(labelColor: Colors.grey, tabs: [
Tab(
text: 'One',
),
Tab(
text: 'two',
)
]),
),
Expanded(
child: Container(child: _tabBarView),
),
],
),
)),
);
}
}
class DemoTab extends StatefulWidget {
DemoTab({
this.parentController
});
final ScrollController parentController;
DemoTabState createState() => DemoTabState();
}
class DemoTabState extends State<DemoTab>
with AutomaticKeepAliveClientMixin<DemoTab> {
@override
// TODO: implement wantKeepAlive
bool get wantKeepAlive => true;
ScrollController _scrollController;
ScrollPhysics ph;
@override
void initState() {
super.initState();
_scrollController = ScrollController();
_scrollController.addListener((){
var innerPos = _scrollController.position.pixels;
var maxOuterPos = widget.parentController.position.maxScrollExtent;
var currentOutPos = widget.parentController.position.pixels;
if(innerPos >= 0 && currentOutPos < maxOuterPos) {
//print("parent pos " + currentOutPos.toString() + "max parent pos " + maxOuterPos.toString());
widget.parentController.position.jumpTo(innerPos+currentOutPos);
}else{
var currenParentPos = innerPos + currentOutPos;
widget.parentController.position.jumpTo(currenParentPos);
}
});
widget.parentController.addListener((){
var currentOutPos = widget.parentController.position.pixels;
if(currentOutPos <= 0) {
_scrollController.position.jumpTo(0);
}
});
}
@override
Widget build(BuildContext context) {
return ListView.builder(
key: UniqueKey(),
controller: _scrollController,
itemBuilder: (b, i) {
return Container(
height: 50,
color: Colors.green,
margin: EdgeInsets.only(bottom: 3),
child: Text(
i.toString(),
),
);
},
itemCount: 30,
);
}
}
以上是 Flutter tabsView和NestedScrollView滚动问题 的全部内容, 来源链接: utcz.com/qa/433599.html