我正在尝试创建原始的原生标签,因此当我们滚动浏览页面时,应用栏会折叠,但该标签栏应始终可见,因此我在Flutter中使用NestedScrollView实现了该操作
class HomeScreen extends StatefulWidget {
@override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> with SingleTickerProviderStateMixin {
TabController _tabController;
@override
void initState() {
super.initState();
_tabController = TabController(length: 2, vsync: this);
}
@override
void dispose() {
super.dispose();
_tabController.dispose();
}
@override
Widget build(BuildContext context) {
return NestedScrollView(
headerSliverBuilder: (BuildContext context, bool isBoxScrolled) {
return [
SliverAppBar(
title: Text("Scroller title"),
forceElevated: isBoxScrolled,
pinned: true,
floating: true,
bottom: TabBar(
tabs: [Tab(text: "tab1"), Tab(text: "tab2")],
controller: _tabController))
];
},
body: TabBarView(
children: [Page1(), Page1()],
controller: _tabController,
));
}
}
class Page1 extends StatefulWidget {
@override
_Page1State createState() => _Page1State();
}
class _Page1State extends State<Page1> {
ScrollController _controller;
void _scrollListener(){
if(_controller.offset >= _controller.position.maxScrollExtent && !_controller.position.outOfRange){
print("reached the bottom");
}
}
@override
void initState() {
super.initState();
_controller = ScrollController();
_controller.addListener(_scrollListener);
}
@override
Widget build(BuildContext context) {
return ListView(
controller: _controller,
children: <Widget>[Text("data"), SizedBox(height: 2000.0)],
);
}
}
但是当我尝试在我的tabBarview小部件之一中使用scrollController时,它将断开与appbar的联系并单独滚动。
答案 0 :(得分:2)
解决方案是PrimaryScrollController
class HomeScreen extends StatefulWidget {
@override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> with SingleTickerProviderStateMixin {
TabController _tabController;
@override
void initState() {
super.initState();
_tabController = TabController(length: 2, vsync: this);
}
@override
void dispose() {
super.dispose();
_tabController.dispose();
}
@override
Widget build(BuildContext context) {
return NestedScrollView(
headerSliverBuilder: (BuildContext context, bool isBoxScrolled) {
return [
SliverAppBar(
title: Text("Scroller title"),
forceElevated: isBoxScrolled,
pinned: true,
floating: true,
bottom: TabBar(
tabs: [Tab(text: "tab1"), Tab(text: "tab2")],
controller: _tabController))
];
},
body: Builder(
builder: (BuildContext context) {
final innerScrollController = PrimaryScrollController.of(context);
// Use the innerScrollController to listen to the scrolling.
// This would be your controller for list. You can listen to this controller to know whether the list has reached maxScrollExtent and fetch data from API.
return TabBarView(
children: [
Page1(innerScrollController),
Page1(innerScrollController)
],
controller: _tabController,
);
},
),
);
}
}
class Page1 extends StatefulWidget {
final ScrollController _PrimaryScrollController;
Page1(this._PrimaryScrollController);
@override
_Page1State createState() => _Page1State();
}
class _Page1State extends State<Page1> {
void _scrollListener(){
if(this.widget._PrimaryScrollController.offset >= this.widget._PrimaryScrollController.position.maxScrollExtent && !this.widget._PrimaryScrollController.position.outOfRange){
print("reached the bottom");
}
}
@override
void initState() {
super.initState();
this.widget._PrimaryScrollController.addListener(_scrollListener);
}
@override
Widget build(BuildContext context) {
return ListView(
children: <Widget>[Text("data"), SizedBox(height: 2000.0)],
);
}
}