對于滾動的視圖,我們經(jīng)常需要監(jiān)聽它的一些滾動事件,在監(jiān)聽到的時候去做對應的一些事情。

在西工等地區(qū),都構建了全面的區(qū)域性戰(zhàn)略布局,加強發(fā)展的系統(tǒng)性、市場前瞻性、產品創(chuàng)新能力,以專注、極致的服務理念,為客戶提供網(wǎng)站制作、做網(wǎng)站 網(wǎng)站設計制作定制制作,公司網(wǎng)站建設,企業(yè)網(wǎng)站建設,品牌網(wǎng)站建設,成都營銷網(wǎng)站建設,外貿營銷網(wǎng)站建設,西工網(wǎng)站建設費用合理。
比如視圖滾動到底部時,我們可能希望做上拉加載更多;
比如滾動到一定位置時顯示一個回到頂部的按鈕,點擊回到頂部的按鈕,回到頂部;
比如監(jiān)聽滾動什么時候開始,什么時候結束;
在Flutter中監(jiān)聽滾動相關的內容由兩部分組成:ScrollController和ScrollNotification。
ScrollController
在Flutter中,Widget并不是最終渲染到屏幕上的元素(真正渲染的是RenderObject),因此通常這種監(jiān)聽事件以及相關的信息并不能直接從Widget中獲取,而是必須通過對應的Widget的Controller來實現(xiàn)。
ListView、GridView的組件控制器是ScrollController,我們可以通過它來獲取視圖的滾動信息,并且可以調用里面的方法來更新視圖的滾動位置。
另外,通常情況下,我們會根據(jù)滾動的位置來改變一些Widget的狀態(tài)信息,所以ScrollController通常會和StatefulWidget一起來使用,并且會在其中控制它的初始化、監(jiān)聽、銷毀等事件。
我們來做一個案例,當滾動到1000位置的時候,顯示一個回到頂部的按鈕:
jumpTo(double offset)、animateTo(double offset,...):這兩個方法用于跳轉到指定的位置,它們不同之處在于,后者在跳轉時會執(zhí)行一個動畫,而前者不會。
ScrollController間接繼承自Listenable,我們可以根據(jù)ScrollController來監(jiān)聽滾動事件。
ListView的基礎創(chuàng)建使用有三種方式:
通過默認構造函數(shù)來創(chuàng)建列表,應用場景 = 短列表
這種方式創(chuàng)建的列表存在一個問題:對于那些長列表或者需要較昂貴渲染開銷的子組件,即使還沒有出現(xiàn)在屏幕中但仍然會被ListView所創(chuàng)建,這將是一項較大的開銷,使用不當可能引起性能問題甚至卡頓。
長列表
列表子項之間需要分割線
ListView的進階使用主要包括:下拉刷新 上拉加載
在Flutter中,ListView結合RefreshIndicator組件實現(xiàn)下拉刷新
通過包裹一層RefreshIndicator,自定義onRefresh回調方法實現(xiàn)
方式有兩種:
通過ListView.controller屬性可以判斷ListView是否滑動到了底部,再進行上拉加載
NotificationListener是一個Widget,可監(jiān)聽子Widget發(fā)出的Notification
ListView在滑動時中會發(fā)出ScrollNotification類型的通知,可通過監(jiān)聽該通知得到ListView的滑動狀態(tài),判斷是否滑動到了底部,從而進行上拉加載
NotificationListener有一個onNotification屬性,定義了監(jiān)聽的回調方法,通過它來處理加載更多邏輯
不定期分享關于 安卓開發(fā) 的干貨,追求 短、平、快 ,但 卻不缺深度 。
最近一個項目要實現(xiàn)可以無限循環(huán)的PageView,主要思路是在初始化pageview的list的時候在開始和結尾多加一個結尾和開頭的widget,當滑動到開頭和結尾的時候手動進行頁面的切換,詳細可以搜索pageview無限輪播。
這種方法有一個要點就是要維護兩個索引,一個是內部list的索引,一個是外部顯示的索引,由于list的容量是比顯示的數(shù)量多2的,所以如果要在外部進行一些比如指示器或者計時器功能要進行和頁面同步顯示或者切換頁面操作時,需要將顯示的索引轉換成list的索引。
不過網(wǎng)上說的都是一些比較簡單的實現(xiàn),看到比較多的就是當滑動到要手動切換的時候進行一個時延,這樣可以避免直接切換頁面造成的卡頓和跳動現(xiàn)象。但是存在一個問題,如果要同時實現(xiàn)一個跟隨頁面切換的指示器,就會出現(xiàn)當頁面切換過去之后指示器才會跟著過去,因為頁面切換的時候執(zhí)行了時延,而時延之后才會真正改變索引,此時才會setstate,之后指示器才能響應到索引的切換,但是如果在時延之前就切換的話又會出現(xiàn)指示器先行的情況。因此這種方法其實是存在一些問題的。
所以解決這個問題的關鍵在于如何進行頁面切換的判斷。這里可以有兩種思路實現(xiàn),第一種是實現(xiàn)viewpage的onpagechanged方法,在里面進行邏輯的判斷,然后用controller來進行頁面跳轉,不過這種方法存在當controller跳轉的時候又會回調onpagechanged,所以就會出現(xiàn)多次對索引不必要操作,而且如果有比如計時器等額外的功能的話可能不方便將頁面邏輯分開,而且依舊無法解決指示器延遲問題,同時也很難進行細粒度的操作。
第二種方法我們就要去看pageview的源碼了,從源碼的角度來解決問題才是正確的方法。首先我們點進去pageview的源碼
看到這里其實已經(jīng)有一些思路了,我們之前難點在于重寫了onpagechanged方法導致問題無法很好的解決,現(xiàn)在我們找到了onpagechanged調用的地方,只要找辦法避免掉就可以實現(xiàn)了。
當然這里我們要說到NotificationListener,以及flutter對應的冒泡事件傳輸機制,這里大家可以去看看這篇 文章 。
我來總結一下,其實就是flutter對于notification這個組件,有一中事件規(guī)則叫冒泡傳遞,底層的notification如果在它的 onNotification寫的邏輯中返回是false以及它不是根結點,就會去向上遍歷尋找它的祖先notification組件,知道遇到root節(jié)點或者某一個返回true,則事件傳遞結束。
而且在onNotification中可以對多種事件進行監(jiān)聽和處理,所以我們可以把對viewpage頁面跳轉對索引處理的邏輯寫在這里,而且我們可以分別處理比如滑動開始的start事件和結束的end事件,分別進行細粒度的邏輯的處理,這樣就可以在外部進行操作和別的功能實現(xiàn)了。
因此不僅無限輪播事件可以通過這種方法來解決,如果有其他的操作也可以這樣進行處理,而且因為我們沒有傳入onpagechanged方法,所以不存在多次調用的問題,pageview那里判斷onpagechanged是null方法就不會進去了,會直接我們寫在pageview外面的notification的邏輯。
最后的結構大概這樣
在移動端,各個平臺或 UI 系統(tǒng)的原始指針事件模型基本都是一致,即:一次完整的事件分為三個階段:手指按下、手指移動、和手指抬起,而更高級別的手勢(如點擊、雙擊、拖動等)都是基于這些原始事件的。
Flutter 中可以使用 Listener widget 來監(jiān)聽原始觸摸事件,它也是一個功能性 widget。
Listener 的常見屬性
用法如下:
加載更多需要對 ListView 進行監(jiān)聽,所以需要進行監(jiān)聽器的設置,在 State 中進行監(jiān)聽器的初始化。
2、使用上述的 Listener 來監(jiān)聽,通過 Listener 的 onPointerMove(手指在屏幕上滑動)來監(jiān)聽滑動的距離,當滑動到底部時加載更多數(shù)據(jù)
Listener 它是主要的功能是用來監(jiān)聽屏幕觸摸事件,取決于它的子組件區(qū)域范圍,比如按下、移動、抬起、取消等操作時可以添加監(jiān)聽。
我們知道 Flutter 組件只有按鈕才會有事件,那么如果我需要在文字或者某個容器上添加事件那我就需要借助 Listener
手勢系列視頻教程地址
Listener 常用于當手指滑動屏幕時進行隱藏鍵盤或者下拉刷新、上拉加載時進行事件監(jiān)聽。
一般在實際的開發(fā)過程中我們很少會用到 Listener 來監(jiān)聽手勢,一般都是通過 GestureDetector 來進行監(jiān)聽或者使用 MouseRegion 來監(jiān)聽鼠標的事件,而 MouseRegion 常用于web開發(fā)中, GestureDetector 常用于app。
我們經(jīng)常使用的回調函數(shù)主要有三個
我們這里主要是針對 onPointerDown 、 onPointerMove 、 onPointerUp 進行演示,因為我們在平時的開發(fā)過程中最常用到的屬性就是這三個,而且其他的屬性也都被廢棄掉了。
我們這里先點擊橙色容器,在點擊一次紅色容器,他們打印的結果如下。
PointerEvent 是觸摸、手寫筆、鼠標事件的基類。
在上文中,我們知道了什么是 Listener 并寫了一個簡單的案例,在使用案例的過程中我們的事件里面都帶了一個 event 參數(shù),而所有的事件最終都是繼承自 PointerEvent ,那我們接下來看看 event 的參數(shù)有什么作用。
PointerEvent 的屬性非常多,但在我們實際的開發(fā)過程中很少會使用到,只有在特定的情景下才會使用對應的屬性。
如需要做一個全局懸浮的按鈕我們會使用到 position
如需要做繪圖軟件我們需要用到 buttons 、 kind 等
所以大家可以根據(jù)實際的應用場景來使用對應的屬性即可,下面是我對 PointerEvent 的屬性進行的一個詳細描述。
behavior 屬性,它決定子組件如何響應命中測試,它的值類型為 HitTestBehavior ,這是一個枚舉類,有三個枚舉值
對子組件一個接一個的進行命中測試,如果子組件中有測試通過的,則當前組件通過,這就意味著,如果指針事件作用于子組件上時,其父級組件也肯定可以收到該事件。
在命中測試時,將當前組件當成不透明處理(即使本身是透明的),最終的效果相當于當前Widget的整個區(qū)域都是點擊區(qū)域
點擊組件透明區(qū)域時,可以對自身邊界內及底部可視區(qū)域都進行命中測試,這意味著點擊頂部組件透明區(qū)域時,頂部組件和底部組件都可以接收到事件
我們這里演示每次都是先點擊綠色盒子在點擊文字,以便大家能更好的分辨出這三個屬性的使用區(qū)別
Listener 是 Flutter 中比較重要的功能性組件,它主要的功能是用來監(jiān)聽屏幕觸摸事件,事件回調可以獲取對應的屬性來個性化定制app功能。
網(wǎng)站欄目:flutter滑動監(jiān)聽,flutter 監(jiān)聽
網(wǎng)頁地址:http://chinadenli.net/article25/dsgipci.html
成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供域名注冊、云服務器、響應式網(wǎng)站、網(wǎng)站收錄、微信公眾號、網(wǎng)站建設
聲明:本網(wǎng)站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經(jīng)允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)