可以在其内部嵌套其他滚动视图的滚动视图,其滚动位置是固有链接的。

在普通的[ScrollView]中, 如果有一个Sliver组件容纳了一个[TabBarView],它沿相反的方向滚动(例如,允许用户在标签所代表的页面之间水平滑动,而列表则垂直滚动),则该[TabBarView]内部的任何列表都不会相互作用 与外部[ScrollView]。 例如,浏览内部列表以滚动到顶部不会导致外部[ScrollView]中的[SliverAppBar]折叠以展开。

定义

  1. const NestedScrollView({
  2. Key key,
  3. this.controller, //滚动控制器,可以监听滚到的位置,设置滚动的位置等
  4. this.scrollDirection = Axis.vertical, //滚动方向,分为垂直和水平方向。
  5. this.reverse = false, //表示反转滚动方向,并不是有垂直转为水平,而是垂直方向滚动时,默认向下滚动,
  6. this.physics, //表示可滚动组件的物理滚动特性
  7. @required this.headerSliverBuilder,
  8. @required this.body,
  9. this.dragStartBehavior = DragStartBehavior.start,
  10. this.floatHeaderSlivers = false,
  11. this.clipBehavior = Clip.hardEdge,
  12. this.restorationId,
  13. })

示例:滚动隐藏AppBar

fdtdttyddasd.gif

  1. import 'package:flutter/material.dart';
  2. class ScrollDemo3 extends StatefulWidget {
  3. @override
  4. _ScrollDemo3State createState() => _ScrollDemo3State();
  5. }
  6. class _ScrollDemo3State extends State<ScrollDemo3> {
  7. @override
  8. Widget build(BuildContext context) {
  9. return NestedScrollView(
  10. headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
  11. return [
  12. SliverAppBar(
  13. title: Text('hello flutter'),
  14. ),
  15. ];
  16. },
  17. body: Container(
  18. child: ListView.builder(
  19. itemCount: 20,
  20. itemBuilder: (context, index) {
  21. return Container(
  22. height: 80,
  23. color: Colors.primaries[index % Colors.primaries.length],
  24. alignment: Alignment.center,
  25. child: Text('文本 $index', style: TextStyle(color: Colors.white, fontSize: 20)),
  26. );
  27. },
  28. ),
  29. ),
  30. );
  31. }
  32. }

示例:SliverAppBar 展开折叠

fdtdttyddasd.gif

  1. headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
  2. return [
  3. SliverAppBar(
  4. expandedHeight: 230.0,
  5. // title: Text('hello flutter'),
  6. pinned: true,
  7. flexibleSpace: FlexibleSpaceBar(
  8. title: Text('复仇者联盟'),
  9. background: Image.network(
  10. 'http://img.haote.com/upload/20180918/2018091815372344164.jpg',
  11. fit: BoxFit.fill,
  12. ),
  13. ),
  14. ),
  15. ];
  16. },

示例:与TabBar配合使用

fdtdttyddasd.gif

  1. import 'package:flutter/material.dart';
  2. class ScrollDemo3 extends StatefulWidget {
  3. @override
  4. _ScrollDemo3State createState() => _ScrollDemo3State();
  5. }
  6. class _ScrollDemo3State extends State<ScrollDemo3> with SingleTickerProviderStateMixin {
  7. TabController _tabController; //tab控制器
  8. @override
  9. void initState() {
  10. super.initState();
  11. _tabController = TabController(length: 2, vsync: this);
  12. }
  13. @override
  14. Widget build(BuildContext context) {
  15. return NestedScrollView(
  16. headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
  17. return [
  18. SliverAppBar(
  19. expandedHeight: 230.0,
  20. pinned: true,
  21. flexibleSpace: FlexibleSpaceBar(
  22. title: Text('复仇者联盟'),
  23. background: Image.network(
  24. 'http://img.haote.com/upload/20180918/2018091815372344164.jpg',
  25. fit: BoxFit.fill,
  26. ),
  27. ),
  28. ),
  29. SliverList(
  30. delegate: SliverChildListDelegate([
  31. Text('fsdfs'),
  32. ]),
  33. ),
  34. SliverPersistentHeader(
  35. pinned: true,
  36. // floating: true,
  37. delegate: StickySliverPersistentHeader(
  38. child: TabBar(
  39. controller: _tabController,
  40. tabs: [
  41. Tab(text: '咨询'),
  42. Tab(text: '技术'),
  43. ],
  44. ),
  45. ),
  46. ),
  47. ];
  48. },
  49. body: Container(
  50. child: TabBarView(
  51. controller: _tabController,
  52. children: [
  53. ListView.builder(
  54. itemCount: 20,
  55. itemBuilder: (context, index) {
  56. return Container(
  57. height: 80,
  58. color: Colors.primaries[index % Colors.primaries.length],
  59. alignment: Alignment.center,
  60. child: Text('咨询 $index', style: TextStyle(color: Colors.white, fontSize: 20)),
  61. );
  62. },
  63. ),
  64. ListView.builder(
  65. itemCount: 20,
  66. itemBuilder: (context, index) {
  67. return Container(
  68. height: 80,
  69. color: Colors.primaries[index % Colors.primaries.length],
  70. alignment: Alignment.center,
  71. child: Text('技术 $index', style: TextStyle(color: Colors.white, fontSize: 20)),
  72. );
  73. },
  74. ),
  75. ],
  76. ),
  77. ),
  78. );
  79. }
  80. }
  81. class StickySliverPersistentHeader extends SliverPersistentHeaderDelegate {
  82. final child;
  83. StickySliverPersistentHeader({@required this.child});
  84. @override
  85. Widget build(BuildContext context, double shrinkOffset, bool overlapsContent) {
  86. return Container(
  87. color: Colors.green,
  88. child: this.child,
  89. );
  90. }
  91. @override
  92. double get minExtent => this.child.preferredSize.height;
  93. double get maxExtent => this.child.preferredSize.height;
  94. @override
  95. bool shouldRebuild(covariant SliverPersistentHeaderDelegate oldDelegate) {
  96. return true;
  97. }
  98. }