介紹
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); }, ), ), ); } }