老孟導讀:【Flutter實戰】系列文章地址:http://laomengit.com/guide/introduction/mobile_system.htmlhtml
默認狀況下,Flutter 的滾動組件(好比 ListView)沒有顯示滾動條,使用 Scrollbar 顯示滾動條:git
Scrollbar( child: ListView.builder( reverse: false, itemBuilder: (BuildContext context, int index) { return Card( child: Container( height: 45, alignment: Alignment.center, child: Text('$index'), ), ); }, itemCount: 30, itemExtent: 50, ), )
在滑動的過程當中,右側顯示滾動條,然而 Scrollbar 沒法實現自定義滾動條的樣式,好比實現以下滾動條樣式,微信
這時須要自定義一個滾動條組件。less
實現自定義滾動條組件首先須要監聽滾動組件 滾動的位置,使用 NotificationListener 監聽滾動的位置:ide
bool _handleScrollNotification(ScrollNotification notification) { final ScrollMetrics metrics = notification.metrics; print('滾動組件最大滾動距離:${metrics.maxScrollExtent}'); print('當前滾動位置:${metrics.pixels}'); return true; } @override Widget build(BuildContext context) { return NotificationListener<ScrollNotification>( onNotification: _handleScrollNotification, child: ListView.builder( reverse: false, itemBuilder: (BuildContext context, int index) { return Card( child: Container( height: 45, alignment: Alignment.center, child: Text('$index'), ), ); }, itemCount: 30, itemExtent: 50, ), ); }
經過 ScrollNotification 獲取當前滾動組件最大滾動距離和當前滾動位置,其中 metrics.maxScrollExtent 表示當前滾動組件最大滾動距離,metrics.pixels 表示當前滾動位置。ui
經過這兩個值計算滾動條在當前屏幕的位置,經過 Stack 組件 將 ListView 和 自定義的滾動條進行疊加顯示:3d
NotificationListener<ScrollNotification>( onNotification: _handleScrollNotification, child: Stack( alignment: Alignment.topRight, children: <Widget>[ ListView.builder( reverse: false, itemBuilder: (BuildContext context, int index) { return Card( child: Container( height: 45, alignment: Alignment.center, child: Text('$index'), ), ); }, itemCount: 30, itemExtent: 50, ), //滾動條 Container( height: 100, width: 20, color: Colors.red, ) ], ), )
將此滾動條和 NotificationListener 監聽到的滾動事件聯動,經過 Container 的 alignment 屬性控制滾動條的位置:code
Container( alignment: Alignment(1, _alignmentY), padding: EdgeInsets.only(right: 5), child: Container( height: 100, width: 20, color: Colors.red, ), )
_alignmentY 就是計算出的偏移位置,計算方法以下:htm
_alignmentY = -1 + (metrics.pixels / metrics.maxScrollExtent) * 2;
這裏要注意 alignment 的座標系:blog
最終效果:
而後只需修改滾動條的樣式便可:
class _ScrollBar extends StatelessWidget { @override Widget build(BuildContext context) { return Container( width: 18, height: 60, decoration: BoxDecoration( shape: BoxShape.rectangle, borderRadius: BorderRadius.all(Radius.circular(20)), color: Colors.blue), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Icon( Icons.arrow_drop_up, size: 18, ), Icon( Icons.arrow_drop_down, size: 18, ), ], ), ); } }
最後將代碼封裝,就能夠給全部的滾動組件添加自定義的滾動條,而不單單是 ListView。
老孟Flutter博客地址(330個控件用法):http://laomengit.com
歡迎加入Flutter交流羣(微信:laomengit)、關注公衆號【老孟Flutter】: