Flutter - 如何将 SliverAppBar 与无限滚动分页一起使用?
Flutter - how using SliverAppBar with Infinite Scroll Pagination?
我在 flutter 的应用程序中使用 Infinite Scroll Pagination 插件。我还需要在我的页面中使用 SilverAppBar。这是我的代码:
return Scaffold(
body: DefaultTabController(
length: 2,
child: NestedScrollView(
headerSliverBuilder: (context, value) {
return [
SliverAppBar(
bottom: TabBar(
tabs: [
Tab(icon: Icon(Icons.call), text: "1"),
Tab(icon: Icon(Icons.message), text: "2"),
],
),
),
];
},
body: TabBarView(
children: [
const MyListWidget()
Text('2')
],
),
),
),
);
这是我的 MyListWidget:
Widget build(BuildContext context) {
return PagedSliverList<int, MyModel>(
pagingController: _сontroller,
builderDelegate: PagedChildBuilderDelegate<MyModel>(
itemBuilder: (context, item, index) {
return Text(item.Title);
},
),
);
}
但是我有错误:
A RenderRepaintBoundary expected a child of type RenderBox but received a child of type RenderSliverList.
我也试过:
body: SliverFillRemaining(
child: TabBarView(
children: [
const ProfileSelections(),
//Container(child: Text('1')),
Text('2')
],
),
)
比但是我有错误:
A RenderSliverFillRemainingWithScrollable expected a child of type RenderBox but received a child of type RenderSliverFillRemainingWithScrollable.
如何修复这些错误?任何建议 - 我将不胜感激
这是因为 tabBarView
需要正常 box children
而不是 slivers
因为它默认使用综合浏览量,您可以在 official documentation.
中阅读
如果您使用普通列表而不是像下面这样的条子,它将解决问题:
Widget build(BuildContext context) {
return PagedListView<int, MyModel>(
pagingController: _сontroller,
builderDelegate: PagedChildBuilderDelegate<MyModel>(
itemBuilder: (context, item, index) {
return Text(item.Title);
},
),
);
}
不用Infinite scroll pagination,直接用flutter自带的滚动通知就可以了
滚动通知 - 抽象class ScrollNotification 使用 ViewportNotificationMixin 扩展 LayoutChangedNotification。
与滚动相关的通知。
可滚动小部件通知其祖先有关滚动相关的更改。
通知具有以下生命周期:
一个ScrollStartNotification,表示widget已经
开始滚动。
零个或多个 ScrollUpdateNotifications,表示
小部件已更改其滚动位置,混合了零个或多个
OverscrollNotifications,表示小部件没有
改变了它的滚动位置,因为改变会导致它的
滚动位置超出其滚动 bounds.Interspersed 与
滚动更新通知和
OverscrollNotifications 是零个或多个 UserScrollNotifications,
这表明用户已经改变了他们的方向
正在滚动。
一个ScrollEndNotification,表示widget已经停止
滚动。
一个 UserScrollNotification,UserScrollNotification.direction
ScrollDirection.idle.
这里是完整的源代码和解释
import 'package:flutter/material.dart';
class InfiniteScrollPagination extends StatefulWidget {
const InfiniteScrollPagination({Key key}) : super(key: key);
@override
_InfiniteScrollPaginationState createState() =>
_InfiniteScrollPaginationState();
}
class _InfiniteScrollPaginationState extends State<InfiniteScrollPagination> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: DefaultTabController(
length: 2,
child: NestedScrollView(
headerSliverBuilder: (context, value) {
return [
SliverAppBar(
pinned: true,
toolbarHeight: 0,
bottom: TabBar(
tabs: [
Tab(icon: Icon(Icons.call), text: "1"),
Tab(icon: Icon(Icons.message), text: "2"),
],
),
),
];
},
body: TabBarView(
children: [MyListWidget(), Text('2')],
),
),
),
);
}
}
class MyListWidget extends StatefulWidget {
const MyListWidget({Key key}) : super(key: key);
@override
State<MyListWidget> createState() => _MyListWidgetState();
}
class _MyListWidgetState extends State<MyListWidget> {
int count = 15;
@override
Widget build(BuildContext context) {
return NotificationListener<ScrollNotification>(
onNotification: (ScrollNotification scrollInfo) {
if (scrollInfo.metrics.pixels == scrollInfo.metrics.maxScrollExtent) {
// here you update your data or load your data from network
setState(() {
count += 10;
});
}
return true;
},
// if you used network it would good to use the stream or future builder
child: Container(
child: getDataList(count),
),
);
}
}
getDataList(listOfData) {
return ListView.separated(
itemBuilder: (context, index) {
return ListTile(
title: Text("index $index"),
);
},
separatorBuilder: (context, index) => Divider(
thickness: 2,
color: Colors.grey,
),
itemCount: listOfData);
}
输出:
使用 PagedListView
而不是 PagedSliverList
可以解决问题。 Slivers 不是小部件,Slivers 以不同的方式呈现。我们主要在 CustomScrollView
小部件中使用 Slivers。
我在 flutter 的应用程序中使用 Infinite Scroll Pagination 插件。我还需要在我的页面中使用 SilverAppBar。这是我的代码:
return Scaffold(
body: DefaultTabController(
length: 2,
child: NestedScrollView(
headerSliverBuilder: (context, value) {
return [
SliverAppBar(
bottom: TabBar(
tabs: [
Tab(icon: Icon(Icons.call), text: "1"),
Tab(icon: Icon(Icons.message), text: "2"),
],
),
),
];
},
body: TabBarView(
children: [
const MyListWidget()
Text('2')
],
),
),
),
);
这是我的 MyListWidget:
Widget build(BuildContext context) {
return PagedSliverList<int, MyModel>(
pagingController: _сontroller,
builderDelegate: PagedChildBuilderDelegate<MyModel>(
itemBuilder: (context, item, index) {
return Text(item.Title);
},
),
);
}
但是我有错误:
A RenderRepaintBoundary expected a child of type RenderBox but received a child of type RenderSliverList.
我也试过:
body: SliverFillRemaining(
child: TabBarView(
children: [
const ProfileSelections(),
//Container(child: Text('1')),
Text('2')
],
),
)
比但是我有错误:
A RenderSliverFillRemainingWithScrollable expected a child of type RenderBox but received a child of type RenderSliverFillRemainingWithScrollable.
如何修复这些错误?任何建议 - 我将不胜感激
这是因为 tabBarView
需要正常 box children
而不是 slivers
因为它默认使用综合浏览量,您可以在 official documentation.
如果您使用普通列表而不是像下面这样的条子,它将解决问题:
Widget build(BuildContext context) {
return PagedListView<int, MyModel>(
pagingController: _сontroller,
builderDelegate: PagedChildBuilderDelegate<MyModel>(
itemBuilder: (context, item, index) {
return Text(item.Title);
},
),
);
}
不用Infinite scroll pagination,直接用flutter自带的滚动通知就可以了
滚动通知 - 抽象class ScrollNotification 使用 ViewportNotificationMixin 扩展 LayoutChangedNotification。
与滚动相关的通知。
可滚动小部件通知其祖先有关滚动相关的更改。
通知具有以下生命周期:
一个ScrollStartNotification,表示widget已经 开始滚动。
零个或多个 ScrollUpdateNotifications,表示 小部件已更改其滚动位置,混合了零个或多个
OverscrollNotifications,表示小部件没有 改变了它的滚动位置,因为改变会导致它的 滚动位置超出其滚动 bounds.Interspersed 与 滚动更新通知和 OverscrollNotifications 是零个或多个 UserScrollNotifications, 这表明用户已经改变了他们的方向 正在滚动。
一个ScrollEndNotification,表示widget已经停止 滚动。
一个 UserScrollNotification,UserScrollNotification.direction ScrollDirection.idle.
这里是完整的源代码和解释
import 'package:flutter/material.dart';
class InfiniteScrollPagination extends StatefulWidget {
const InfiniteScrollPagination({Key key}) : super(key: key);
@override
_InfiniteScrollPaginationState createState() =>
_InfiniteScrollPaginationState();
}
class _InfiniteScrollPaginationState extends State<InfiniteScrollPagination> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: DefaultTabController(
length: 2,
child: NestedScrollView(
headerSliverBuilder: (context, value) {
return [
SliverAppBar(
pinned: true,
toolbarHeight: 0,
bottom: TabBar(
tabs: [
Tab(icon: Icon(Icons.call), text: "1"),
Tab(icon: Icon(Icons.message), text: "2"),
],
),
),
];
},
body: TabBarView(
children: [MyListWidget(), Text('2')],
),
),
),
);
}
}
class MyListWidget extends StatefulWidget {
const MyListWidget({Key key}) : super(key: key);
@override
State<MyListWidget> createState() => _MyListWidgetState();
}
class _MyListWidgetState extends State<MyListWidget> {
int count = 15;
@override
Widget build(BuildContext context) {
return NotificationListener<ScrollNotification>(
onNotification: (ScrollNotification scrollInfo) {
if (scrollInfo.metrics.pixels == scrollInfo.metrics.maxScrollExtent) {
// here you update your data or load your data from network
setState(() {
count += 10;
});
}
return true;
},
// if you used network it would good to use the stream or future builder
child: Container(
child: getDataList(count),
),
);
}
}
getDataList(listOfData) {
return ListView.separated(
itemBuilder: (context, index) {
return ListTile(
title: Text("index $index"),
);
},
separatorBuilder: (context, index) => Divider(
thickness: 2,
color: Colors.grey,
),
itemCount: listOfData);
}
输出:
使用 PagedListView
而不是 PagedSliverList
可以解决问题。 Slivers 不是小部件,Slivers 以不同的方式呈现。我们主要在 CustomScrollView
小部件中使用 Slivers。