介绍
ViewPort视口
在很多布局系统中都有ViewPort的概念,在Flutter中,术语ViewPort(视口),如无特别说明,则是指一个Widget的实际显示区域。例如,一个
ListView
的显示区域高度是800像素,虽然其列表项总高度可能远远超过800像素,但是其ViewPort仍然是800像素。Scrollbar
Scrollbar
是一个Material风格的滚动指示器(滚动条),如果要给可滚动组件添加滚动条,只需将Scrollbar
作为可滚动组件的任意一个父级组件即可CupertinoScrollbar
CupertinoScrollbar
是iOS风格的滚动条,如果使用的是Scrollbar
,那么在iOS平台它会自动切换为CupertinoScrollbar
基于Sliver的延迟构建
通常可滚动组件的子组件可能会非常多、占用的总高度也会非常大;如果要一次性将子组件全部构建出将会非常昂贵!为此,Flutter中提出一个Sliver(中文为“薄片”的意思)概念,如果一个可滚动组件支持Sliver模型,那么该滚动可以将子组件分成好多个“薄片”(Sliver),只有当Sliver出现在视口中时才会去构建它,这种模型也称为“基于Sliver的延迟构建模型”。可滚动组件中有很多都支持基于Sliver的延迟构建模型,如
ListView
、GridView
,但是也有不支持该模型的,如SingleChildScrollView
ScrollController
ScrollController
间接继承自Listenable
,我们可以根据ScrollController
来监听滚动事件,可以用
ScrollController
来控制可滚动组件的滚动位置
offset 可滚动组件 当前的滚动位置
jumpTo
animateTo
跳转到指定的位置,
它们不同之处在于,后者在跳转时会执行一个动画,而前者不会
dispose 为了避免内存泄露,需要调用 controller.dispose demo
import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; void main() { runApp(MyAppText()); } class MyAppText extends StatefulWidget { @override ListViewClass createState() { return ListViewClass(); } } class ListViewClass extends State { ScrollController _controller=new ScrollController(); @override void dispose() { _controller.dispose(); super.dispose(); } @override void initState() { // TODO: implement initState super.initState(); _controller.addListener((){ print(_controller.offset); }); } @override Widget build(BuildContext context) { // TODO: implement build List<String> list = new List(); for (int i = 0; i < 100; i++) { list.add("我和我的祖国$i"); } return MaterialApp( home: Scaffold( appBar: AppBar( backgroundColor: Colors.red, title: Text('Controller练习'), textTheme: TextTheme(title: TextStyle(fontSize: 18, color: Colors.yellow)), ), body: Scrollbar( child: ListView.separated( controller: _controller, separatorBuilder: (BuildContext context, int dex) { return Divider( color: Colors.blue, height: 1, ); }, itemCount: list.length, itemBuilder: (BuildContext context, int dex) { return ListTile( title: Text('${list[dex]}'), ); }, ), ), floatingActionButton: FloatingActionButton( child: Icon(Icons.arrow_upward), onPressed: (){ // _controller.jumpTo(0);//点击按钮回调顶部 _controller.animateTo(0, duration: Duration( milliseconds: 300 ), curve: Curves.ease); }, ), ), ); } }