<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
實現的效果是這樣的:
剛開始的時候,是在dev上找了兩個輪子,簡單測了下,都不太滿意,滑動事件處理的比較粗糙,總有bug。就在想著,要不要拿原始碼改一版的時候,讓我無意間看到了這個貼文
裡面的想法,大開眼界,是通過 DraggableScrollableSheet 和 IgnorePointer 來完美實現上面的效果。
這是 DraggableScrollableSheet 的程式碼,
DraggableScrollableSheet( maxChildSize: 0.8, minChildSize: 0.25, // 注意都是佔父元件的比例 initialChildSize: 0.25, expand: true, builder: (BuildContext context, ScrollController controller) { return Stack(); // body列表和header欄都在stack內 }, )
這是 body 列表和 header,這裡的 body 是個 list,
Stack( children: [ Container( color: Colors.blue, child: Body( // ListView.separated controller: controller, paddingTop: headerHeight, // 防止壓蓋 ), ), const IgnorePointer( // 這裡不接收事件,所以拖動 header 也能夠滑動頁面 child: Header( // Container[Center[Text]] height: headerHeight, ), ), ], )
但如果我們想在 header 內加點選事件呢?那在 Stack header 上層再加 widget 就好了。
程式碼就這點,我放在了 gitHub 上,感興趣的可以看下。
2022.8.23 補充:
這是在上面功能基礎上的一個小擴充套件,即當滑動距離超過一半則自動滾至頂部,反之回到底部,來看下效果:
思路也很簡單,首先我要知道當前捲動的距離或其佔比,DraggableScrollableController 提供了這個能力:
void _draggableScrollListener() { // [_currStale] 記錄下當前的佔比 // [_controller.size] 即佔比, 範圍[minChildSize,maxChildSize] // [_controller.pixels] 即距離 if (_currStale != _controller.size) { _currStale = _controller.size; } debugPrint('[listener] size: ${_controller.size}' ', pixels : ${_controller.pixels}'); }
其次要知道使用者何時停止了捲動,我們可以使用 NotificationListener 來監聽 DraggableScrollableSheet 的捲動狀態:
NotificationListener<ScrollNotification>( onNotification: (ScrollNotification notification) { ... return false; }, child: DraggableScrollableSheet(...),
之後在使用者停止捲動的時候,我們判斷當前距離,並根據結果讓 DraggableScrollableSheet 自動捲動到頂部或底部。
onNotification: (ScrollNotification notification) { if (_animation) { // 動畫中,不處理狀態 return false; } if (notification is ScrollStartNotification) { debugPrint('start scroll'); } else if (notification is ScrollEndNotification) { debugPrint('stop scroll'); // 通過 [_controller.animateTo] 方法捲動 _scrollAnimation(); } return false;
在 _scrollAnimation 內就是捲動的方法了,這裡要注意的是,不能直接使用 await Feature,我測試在頻繁不同方向滑動時,可能會導致方法被掛起。在這直接 dedelayed(duration: xx) 即可:
Future<void> _scrollAnimation() async { if (_animation) { return; } _animation = true; //debugPrint('async start'); final int duration; // `await`ing the returned Feature(of [animateTo]) may cause the method to hang // So, Start a timer to set [_animation]. if (_currStale >= (_maxScale + _minScale) * 0.5) { duration = (_duration * ((_maxScale - _currStale) / (_maxScale - _minScale))) .toInt(); if (duration == 0) { _animation = false; return; } else { // [duration] control speed, Avoid situations where it's equal to 0 _animationTo(_maxScale, duration); } } else { duration = (_duration * ((_currStale - _minScale) / (_maxScale - _minScale))) .toInt(); if (duration == 0) { _animation = false; return; } else { _animationTo(_minScale, duration); } } Future.delayed( Duration(milliseconds: duration), ).then((value) => { //debugPrint('async stop'), _animation = false, }); }
其中 _animationTo
是實際控制控制元件捲動的方法:
void _animationTo(double scale, int duration) { _controller.animateTo( scale, duration: Duration(milliseconds: duration), curve: Curves.ease, ); }
2022.9.24 補充:
那如果再提供一種通過點選按鈕來控制 DraggableScrollableSheet
收起和彈出的方法呢?
我們可以直接這樣,是不是很簡單:
Future<void> _scrollAnimation2() async { if (_animation) { return; } if (_currStale > (_maxScale + _minScale) * 0.5) { _animationTo(_minScale, _duration); } else { _animationTo(_maxScale, _duration); } }
以上就是Flutter實現固定header底部滑動頁效果範例的詳細內容,更多關於Flutter固定header底部滑動頁的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45