问题描述
我有一个"NestedScrollView",其中包含多个"TabView"小部件,并且每个选项卡都有一个列表生成器.问题在于,当我滚动浏览特定选项卡中的一个列表时,滚动位置会影响其他选项卡中的所有其他列表.
I have a "NestedScrollView" that contains multiple "TabView" widgets and each one of those tabs has a list builder. The problem is that when i scroll through one list in a specific tab, the scroll position affects all the other lists in the other tabs.
即使我确实将"ScrollController"添加到每个listview(在选项卡中),选项卡滚动中的listBuilder也会与"NestedScrollView"分开这是示例代码:
Even if i do add "ScrollController" to each of the listview (in tabs), The listBuilder inside the tab scroll gets separated from the "NestedScrollView"here is an example code :
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,) ;
}
}
推荐答案
三天后,我发现这是解决此问题的最佳方法,但仍需要更多改进,因为条头割管扩展和收缩过快,可以改进代码,然后与我们分享
after 3 days i found this is the best solution to this problem ,but still need more improvement , cuz the sliver header expand and shrink too fast , you can improve code , and share us
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滚动问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!