image.png

ScrollController

构造函数

  1. ScrollController({
  2. double initialScrollOffset = 0.0, //初始滚动位置
  3. this.keepScrollOffset = true, //是否保存滚动位置
  4. this.debugLabel,
  5. })

常用方法

  • offset:可滚动组件当前的滚动位置
  • jumpTo(double offset)animateTo(double offset,...):这两个方法用于跳转到指定的位置,它们不同之处在于,后者在跳转时会执行一个动画,而前者不会。
  • addListener() 添加滚动的监听,可以获取滚动过的位置。
  • dispose(),在widget的dispose时调用,避免内存泄漏
  • _scrollController.position.pixels 滑动距离
  • _scrollController.offset 滑动距离
  • _scrollController.position.maxScrollExtent 最大可滑动距离
  • _scrollController.position.minScrollExtent 最小可滑动距离
  • _scrollController.position.viewportDimension 滚动视图所占长度

    例子1: 点击回到顶部

  1. import 'package:flutter/cupertino.dart';
  2. import 'package:flutter/material.dart';
  3. class MinePage extends StatefulWidget {
  4. @override
  5. _MinePageState createState() => _MinePageState();
  6. }
  7. class _MinePageState extends State<MinePage> {
  8. ScrollController _controller = new ScrollController();
  9. bool showToTopBtn = false; //是否显示“返回到顶部”按钮
  10. @override
  11. void dispose() {
  12. // TODO: implement dispose
  13. //为了避免内存泄露,需要调用_controller.dispose
  14. _controller.dispose();
  15. super.dispose();
  16. }
  17. @override
  18. void initState() {
  19. // TODO: implement initState
  20. super.initState();
  21. _controller.addListener(() {
  22. print(_controller.offset); //打印offset
  23. //当offset小于500并且,showToTopBtn= true的时,显示返回按钮
  24. if (_controller.offset < 500 && showToTopBtn) {
  25. setState(() {
  26. showToTopBtn = false;
  27. });
  28. } else if (_controller.offset >= 500 && showToTopBtn == false) {
  29. setState(() {
  30. showToTopBtn = true;
  31. });
  32. }
  33. });
  34. }
  35. @override
  36. Widget build(BuildContext context) {
  37. return Scaffold(
  38. body: CustomScrollView(
  39. controller: _controller,
  40. slivers: <Widget>[
  41. SliverAppBar(
  42. pinned: true,
  43. stretch: true,
  44. expandedHeight: 200.0,
  45. flexibleSpace: FlexibleSpaceBar(
  46. title: Text('开学季'),
  47. background: Image.network(
  48. "https://goss.cfp.cn/creative/vcg/800/new/VCG211165042753.jpg",
  49. fit: BoxFit.cover,
  50. ),
  51. ),
  52. ),
  53. SliverPadding(
  54. padding: EdgeInsets.only(top: 10),
  55. ),
  56. SliverFixedExtentList(
  57. itemExtent: 66, //固定高度
  58. delegate: SliverChildBuilderDelegate(
  59. (context, index) {
  60. Color color =
  61. index % 2 == 0 ? Colors.orange : Colors.deepOrangeAccent;
  62. return Container(
  63. alignment: Alignment.center,
  64. color: color,
  65. child: Text('$index'),
  66. );
  67. },
  68. childCount: 50,
  69. ),
  70. ),
  71. ],
  72. ),
  73. floatingActionButton: !showToTopBtn ? null : FloatingActionButton(
  74. child: Icon(Icons.arrow_upward),
  75. onPressed: () {
  76. //返回到顶部时执行动画
  77. _controller.animateTo(.0,
  78. duration: Duration(milliseconds: 200),
  79. curve: Curves.ease
  80. );
  81. }
  82. ),
  83. );
  84. }
  85. }

2020-04-14 08.38.43.gif