【Flutter實戰】自定義滾動條

来源:https://www.cnblogs.com/mengqd/archive/2020/06/29/13205929.html
-Advertisement-
Play Games

老孟導讀:【Flutter實戰】系列文章地址:http://laomengit.com/guide/introduction/mobile_system.html 預設情況下,Flutter 的滾動組件(比如 ListView)沒有顯示滾動條,使用 Scrollbar 顯示滾動條: Scrollba ...


老孟導讀:【Flutter實戰】系列文章地址:http://laomengit.com/guide/introduction/mobile_system.html

預設情況下,Flutter 的滾動組件(比如 ListView)沒有顯示滾動條,使用 Scrollbar 顯示滾動條:

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 無法實現自定義滾動條的樣式,比如實現如下滾動條樣式,

這時需要自定義一個滾動條組件。

實現自定義滾動條組件首先需要監聽滾動組件 滾動的位置,使用 NotificationListener 監聽滾動的位置:

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 表示當前滾動位置。

通過這兩個值計算滾動條在當前屏幕的位置,通過 Stack 組件 將 ListView 和 自定義的滾動條進行疊加顯示:

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 屬性控制滾動條的位置:

Container(
  alignment: Alignment(1, _alignmentY),
  padding: EdgeInsets.only(right: 5),
  child: Container(
    height: 100,
    width: 20,
    color: Colors.red,
  ),
)

_alignmentY 就是計算出的偏移位置,計算方法如下:

_alignmentY = -1 + (metrics.pixels / metrics.maxScrollExtent) * 2;

這裡要註意 alignment 的坐標系:

最終效果:

然後只需修改滾動條的樣式即可:

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】:


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1、年齡的問題。年齡確實是一個必須考慮的重要問題,30歲大多已成家,可能已經有了小孩,分給家庭的時間會越來越多,能夠投入的時間和精力必然比不上20出頭的小伙子。但我認為精力反而不是最大的問題,最大的問題是越來越輸不起。到了30歲的人應該都有體會,你做的每一個決策都有很高的機會成本,是牽一發而動全身的 ...
  • 因為所出標簽太多,所以我們很難都用得上或者意識到需要用。 但其實也有許多有趣但是我們未曾發掘的標簽,本文所要介紹的 便是一個。 <dataList>是什麼? 標簽一個類似於 標簽一樣可以通過包裹 來表示控制項可選值的,唯一不同的就是 需要配合 來使用,而且 不表示任何內容,僅作展示。 我們康個慄子: ...
  • 本案例製作一個咖啡銷售網站,通過網站呈現自己的理念和咖啡文化,頁面佈局設計獨特,採用兩欄的佈局形式;頁面風格設計簡潔,為瀏覽者提供一個簡單、時尚的頁面,瀏覽時讓人心情舒暢。 1、網站概述網站的設計思路和設計風格與Bootstrap框架風格完美融合,下麵就來具體地介紹實現的步驟。 2、網站結構 本案例 ...
  • 盒模型 盒模型主要兩種,標準盒模型和怪異和模型 標準盒模型:width指content部分的寬度 怪異盒模型:width指content、padding、border的總寬度 解決方法:box-sizing屬性,值為content-box(標準盒模型),值為border-box(怪異盒模型) 垂直居 ...
  • /** * 對象、數組變化監聽(增刪改) * @author w-bing * @date 2020-04-22 * @param {Object} obj * @param {Function} cb * @return {Proxy} */ function deepProxy(obj, cb) ...
  • Laravel 如何在blade文件中使用Vue組件 1. 安裝laravel/ui依賴包 composer require laravel/ui 2.生成vue基本腳手架 php artisan ui react 系統還提供了非常便捷的auth腳手架,帶登錄註冊。 php artisan ui r ...
  • 一、Overview Angular 入坑記錄的筆記第七篇,介紹 Angular 中的模塊的相關概念,瞭解相關的使用場景,以及知曉如何通過特性模塊來組織我們的 Angular 應用 對應官方文檔地址: NgModule 簡介 NgModules JavaScript 模塊 vs. NgModule ...
  • 一、sentinel是什麼 sentinel的官方名稱叫分散式系統的流量防衛兵。Sentinel 以流量為切入點,從流量控制、熔斷降級、系統負載保護等多個維度保護服務的穩定性。在Spring Cloud項目中最開始我們使用的是Hystrix,目前已停止更新了。現在Spring Cloud官方推薦的是 ...
一周排行
    -Advertisement-
    Play Games
  • .Net8.0 Blazor Hybird 桌面端 (WPF/Winform) 實測可以完整運行在 win7sp1/win10/win11. 如果用其他工具打包,還可以運行在mac/linux下, 傳送門BlazorHybrid 發佈為無依賴包方式 安裝 WebView2Runtime 1.57 M ...
  • 目錄前言PostgreSql安裝測試額外Nuget安裝Person.cs模擬運行Navicate連postgresql解決方案Garnet為什麼要選擇Garnet而不是RedisRedis不再開源Windows版的Redis是由微軟維護的Windows Redis版本老舊,後續可能不再更新Garne ...
  • C#TMS系統代碼-聯表報表學習 領導被裁了之後很快就有人上任了,幾乎是無縫銜接,很難讓我不想到這早就決定好了。我的職責沒有任何變化。感受下來這個系統封裝程度很高,我只要會調用方法就行。這個系統交付之後不會有太多問題,更多應該是做小需求,有大的開發任務應該也是第二期的事,嗯?怎麼感覺我變成運維了?而 ...
  • 我在隨筆《EAV模型(實體-屬性-值)的設計和低代碼的處理方案(1)》中介紹了一些基本的EAV模型設計知識和基於Winform場景下低代碼(或者說無代碼)的一些實現思路,在本篇隨筆中,我們來分析一下這種針對通用業務,且只需定義就能構建業務模塊存儲和界面的解決方案,其中的數據查詢處理的操作。 ...
  • 對某個遠程伺服器啟用和設置NTP服務(Windows系統) 打開註冊表 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W32Time\TimeProviders\NtpServer 將 Enabled 的值設置為 1,這將啟用NTP伺服器功 ...
  • title: Django信號與擴展:深入理解與實踐 date: 2024/5/15 22:40:52 updated: 2024/5/15 22:40:52 categories: 後端開發 tags: Django 信號 松耦合 觀察者 擴展 安全 性能 第一部分:Django信號基礎 Djan ...
  • 使用xadmin2遇到的問題&解決 環境配置: 使用的模塊版本: 關聯的包 Django 3.2.15 mysqlclient 2.2.4 xadmin 2.0.1 django-crispy-forms >= 1.6.0 django-import-export >= 0.5.1 django-r ...
  • 今天我打算整點兒不一樣的內容,通過之前學習的TransformerMap和LazyMap鏈,想搞點不一樣的,所以我關註了另外一條鏈DefaultedMap鏈,主要調用鏈為: 調用鏈詳細描述: ObjectInputStream.readObject() DefaultedMap.readObject ...
  • 後端應用級開發者該如何擁抱 AI GC?就是在這樣的一個大的浪潮下,我們的傳統的應用級開發者。我們該如何選擇職業或者是如何去快速轉型,跟上這樣的一個行業的一個浪潮? 0 AI金字塔模型 越往上它的整個難度就是職業機會也好,或者說是整個的這個運作也好,它的難度會越大,然後越往下機會就會越多,所以這是一 ...
  • @Autowired是Spring框架提供的註解,@Resource是Java EE 5規範提供的註解。 @Autowired預設按照類型自動裝配,而@Resource預設按照名稱自動裝配。 @Autowired支持@Qualifier註解來指定裝配哪一個具有相同類型的bean,而@Resourc... ...