最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Flutter之可滾動(dòng)組件實(shí)例詳解

 更新時(shí)間:2022年10月31日 16:44:15   作者:風(fēng)雨_83  
這篇文章主要為大家介紹了Flutter之可滾動(dòng)組件實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

正文

當(dāng)內(nèi)容超過顯示視口(ViewPort)時(shí),如果沒有特殊處理,F(xiàn)lutter則會提示Overflow錯(cuò)誤。為此,F(xiàn)lutter提供了多種可滾動(dòng)widget(Scrollable Widget)用于顯示列表和長布局。

Flutter中有兩種布局模型:

  • 基于 RenderBox 的盒模型布局。
  • 基于 Sliver ( RenderSliver ) 按需加載列表布局。

通??蓾L動(dòng)組件的子組件可能會非常多、占用的總高度也會非常大;如果要一次性將子組件全部構(gòu)建出將會非常昂貴!為此,F(xiàn)lutter中提出一個(gè)Sliver(中文為“薄片”的意思)概念,Sliver 可以包含一個(gè)或多個(gè)子組件。Sliver 的主要作用是配合:加載子組件并確定每一個(gè)子組件的布局和繪制信息,如果 Sliver 可以包含多個(gè)子組件時(shí),通常會實(shí)現(xiàn)按需加載模型。

只有當(dāng)Sliver 出現(xiàn)在視口中時(shí)才會去構(gòu)建它,這種模型也稱為“基于Sliver的列表按需加載模型”??蓾L動(dòng)組件中有很多都支持基于Sliver的按需加載模型,如ListView、GridView,但是也有不支持該模型的,如SingleChildScrollView

Flutter 中的可滾動(dòng)主要由三個(gè)角色組成:Scrollable、Viewport 和 Sliver:

  • Scrollable :用于處理滑動(dòng)手勢,確定滑動(dòng)偏移,滑動(dòng)偏移變化時(shí)構(gòu)建 Viewport 。
  • Viewport:顯示的視窗,即列表的可視區(qū)域;
  • Sliver:視窗里顯示的元素。

具體布局過程:

  • Scrollable 監(jiān)聽到用戶滑動(dòng)行為后,根據(jù)最新的滑動(dòng)偏移構(gòu)建 Viewport 。
  • Viewport 將當(dāng)前視口信息和配置信息通過 SliverConstraints 傳遞給 Sliver。
  • Sliver 中對子組件(RenderBox)按需進(jìn)行構(gòu)建和布局,然后確認(rèn)自身的位置、繪制等信息,保存在 geometry 中(一個(gè) SliverGeometry 類型的對象)

比如有一個(gè) ListView,大小撐滿屏幕,假設(shè)它有 100 個(gè)列表項(xiàng)(都是RenderBox)且每個(gè)列表項(xiàng)高度相同,結(jié)構(gòu)如下:

圖中白色區(qū)域?yàn)樵O(shè)備屏幕,也是 Scrollable 、 Viewport 和 Sliver 所占用的空間,三者所占用的空間重合,父子關(guān)系為:Sliver 父組件為 Viewport,Viewport的 父組件為 Scrollable 。注意ListView 中只有一個(gè) Sliver,在 Sliver 中實(shí)現(xiàn)了子組件的按需加載。

其中頂部和底部灰色的區(qū)域?yàn)?cacheExtent,它表示預(yù)渲染的高度,需要注意這是在可視區(qū)域之外,如果 RenderBox 進(jìn)入這個(gè)區(qū)域內(nèi),即使它還未顯示在屏幕上,也是要先進(jìn)行構(gòu)建的,預(yù)渲染是為了后面進(jìn)入 Viewport 的時(shí)候更絲滑。cacheExtent 的默認(rèn)值是 250,在構(gòu)建可滾動(dòng)列表時(shí)我們可以指定這個(gè)值,這個(gè)值最終會傳給 Viewport。

Scrollable

用于處理滑動(dòng)手勢,確定滑動(dòng)偏移,滑動(dòng)偏移變化時(shí)構(gòu)建 Viewport,我們看一下其關(guān)鍵的屬性:

Scrollable({
  ...
  this.axisDirection = AxisDirection.down,
  this.controller,
  this.physics,
  required this.viewportBuilder, //后面介紹
})
  • axisDirection 滾動(dòng)方向。
  • physics:此屬性接受一個(gè)ScrollPhysics類型的對象,它決定可滾動(dòng)組件如何響應(yīng)用戶操作,比如用戶滑動(dòng)完抬起手指后,繼續(xù)執(zhí)行動(dòng)畫;或者滑動(dòng)到邊界時(shí),如何顯示。默認(rèn)情況下,F(xiàn)lutter會根據(jù)具體平臺分別使用不同的ScrollPhysics對象,應(yīng)用不同的顯示效果,如當(dāng)滑動(dòng)到邊界時(shí),繼續(xù)拖動(dòng)的話,在 iOS 上會出現(xiàn)彈性效果,而在 Android 上會出現(xiàn)微光效果。如果你想在所有平臺下使用同一種效果,可以顯式指定一個(gè)固定的ScrollPhysics,F(xiàn)lutter SDK中包含了兩個(gè)ScrollPhysics的子類,他們可以直接使用:
AlwaysScrollableScrollPhysics:總是可以滑動(dòng)
NeverScrollableScrollPhysics:禁止?jié)L動(dòng)
BouncingScrollPhysics :內(nèi)容超過一屏 上拉有回彈效果
ClampingScrollPhysics :包裹內(nèi)容 不會有回彈
  • controller:此屬性接受一個(gè)ScrollController對象。ScrollController的主要作用是控制滾動(dòng)位置和監(jiān)聽滾動(dòng)事件。默認(rèn)情況下,Widget樹中會有一個(gè)默認(rèn)的PrimaryScrollController,如果子樹中的可滾動(dòng)組件沒有顯式的指定controller,并且primary屬性值為true時(shí)(默認(rèn)就為true),可滾動(dòng)組件會使用這個(gè)默認(rèn)的PrimaryScrollController。這種機(jī)制帶來的好處是父組件可以控制子樹中可滾動(dòng)組件的滾動(dòng)行為,例如,Scaffold正是使用這種機(jī)制在iOS中實(shí)現(xiàn)了點(diǎn)擊導(dǎo)航欄回到頂部的功能。
  • viewportBuilder:構(gòu)建 Viewport 的回調(diào)。當(dāng)用戶滑動(dòng)時(shí),Scrollable 會調(diào)用此回調(diào)構(gòu)建新的 Viewport,同時(shí)傳遞一個(gè) ViewportOffset 類型的 offset 參數(shù),該參數(shù)描述 Viewport 應(yīng)該顯示那一部分內(nèi)容。注意重新構(gòu)建 Viewport 并不是一個(gè)昂貴的操作,因?yàn)?Viewport 本身也是 Widget,只是配置信息,Viewport 變化時(shí)對應(yīng)的 RenderViewport 會更新信息,并不會隨著 Widget 進(jìn)行重新構(gòu)建。

主軸和縱軸

在可滾動(dòng)組件的坐標(biāo)描述中,通常將滾動(dòng)方向稱為主軸,非滾動(dòng)方向稱為縱軸。由于可滾動(dòng)組件的默認(rèn)方向一般都是沿垂直方向,所以默認(rèn)情況下主軸就是指垂直方向,水平方向同理。

Viewport

Viewport 比較簡單,用于渲染當(dāng)前視口中需要顯示 Sliver。

Viewport({
  Key? key,
  this.axisDirection = AxisDirection.down,
  this.crossAxisDirection,
  this.anchor = 0.0,
  required ViewportOffset offset, // 用戶的滾動(dòng)偏移
  // 類型為Key,表示從什么地方開始繪制,默認(rèn)是第一個(gè)元素
  this.center,
  this.cacheExtent, // 預(yù)渲染區(qū)域
  //該參數(shù)用于配合解釋cacheExtent的含義,也可以為主軸長度的乘數(shù)
  this.cacheExtentStyle = CacheExtentStyle.pixel, 
  this.clipBehavior = Clip.hardEdge,
  List<Widget> slivers = const <Widget>[], // 需要顯示的 Sliver 列表
})

需要注意的是:

  • offset:該參數(shù)為Scrollabel 構(gòu)建 Viewport 時(shí)傳入,它描述了 Viewport 應(yīng)該顯示那一部分內(nèi)容。
  • cacheExtent 和 cacheExtentStyle:CacheExtentStyle 是一個(gè)枚舉,有 pixel 和 viewport 兩個(gè)取值。當(dāng) cacheExtentStyle 值為 pixel 時(shí),cacheExtent 的值為預(yù)渲染區(qū)域的具體像素長度;當(dāng)值為 viewport 時(shí),cacheExtent 的值是一個(gè)乘數(shù),表示有幾個(gè) viewport 的長度,最終的預(yù)渲染區(qū)域的像素長度為:cacheExtent * viewport 的積, 這在每一個(gè)列表項(xiàng)都占滿整個(gè) Viewport 時(shí)比較實(shí)用,這時(shí) cacheExtent 的值就表示前后各緩存幾個(gè)頁面。

Sliver

Sliver 主要作用是對子組件進(jìn)行構(gòu)建和布局,比如 ListView 的 Sliver 需要實(shí)現(xiàn)子組件(列表項(xiàng))按需加載功能,只有當(dāng)列表項(xiàng)進(jìn)入預(yù)渲染區(qū)域時(shí)才會去對它進(jìn)行構(gòu)建和布局、渲染。

Sliver 對應(yīng)的渲染對象類型是 RenderSliver,RenderSliver 和 RenderBox 的相同點(diǎn)是都繼承自 RenderObject 類,不同點(diǎn)是在布局的時(shí)候約束信息不同。RenderBox 在布局時(shí)父組件傳遞給它的約束信息對應(yīng)的是 BoxConstraints,只包含最大寬高的約束;而 RenderSliver 在布局時(shí)父組件(列表)傳遞給它的約束是對應(yīng)的是 SliverConstraints。

可滾動(dòng)組件的通用配置

幾乎所有的可滾動(dòng)組件在構(gòu)造時(shí)都能指定 scrollDirection(滑動(dòng)的主軸)、reverse(滑動(dòng)方向是否反向)、controller、physics 、cacheExtent ,這些屬性最終會透傳給對應(yīng)的 Scrollable 和 Viewport,這些屬性我們可以認(rèn)為是可滾動(dòng)組件的通用屬性.

reverse表示是否按照閱讀方向相反的方向滑動(dòng),如:scrollDirection值為Axis.horizontal 時(shí),即滑動(dòng)發(fā)現(xiàn)為水平,如果閱讀方向是從左到右。

reversetrue時(shí),那么滑動(dòng)方向就是從右往左。

ScrollController

可滾動(dòng)組件都有一個(gè) controller 屬性,通過該屬性我們可以指定一個(gè) ScrollController 來控制可滾動(dòng)組件的滾動(dòng),比如可以通過ScrollController來同步多個(gè)組件的滑動(dòng)聯(lián)動(dòng)。

子節(jié)點(diǎn)緩存

按需加載子組件在大多數(shù)場景中都能有正收益,但是有些時(shí)候也會有副作用。比如有一個(gè)頁面,它由一個(gè)ListView 組成,我們希望在頁面頂部顯示一塊內(nèi)容, 這部分內(nèi)容的數(shù)據(jù)需要在每次頁面打開時(shí)通過網(wǎng)絡(luò)來獲取,為此我們通一個(gè) Header 組件來實(shí)現(xiàn),它是一個(gè) StatefulWidget ,會在initState 中請求網(wǎng)絡(luò)數(shù)據(jù),然后將它作為 ListView 的第一個(gè)孩子?,F(xiàn)在問題來了,因?yàn)?ListView 是按需加載子節(jié)點(diǎn)的,這意味著如果 Header 滑出 Viewport 的預(yù)渲染區(qū)域之外時(shí)就會被銷毀,重新滑入后又會被重新構(gòu)建,這樣就會發(fā)起多次網(wǎng)絡(luò)請求,不符合我們期望。

為了解決上述問題,可滾動(dòng)組件提供了一種緩存子節(jié)點(diǎn)的通用解決方案,它允許開發(fā)者對特定的子界限進(jìn)行緩存.

Scrollbar

Scrollbar是一個(gè)Material風(fēng)格的滾動(dòng)指示器(滾動(dòng)條),如果要給可滾動(dòng)組件添加滾動(dòng)條,只需將Scrollbar作為可滾動(dòng)組件的任意一個(gè)父級組件即可,如:

Scrollbar(
  child: SingleChildScrollView(
    ...
  ),
);

ScrollbarCupertinoScrollbar都是通過監(jiān)聽滾動(dòng)通知來確定滾動(dòng)條位置的。

CupertinoScrollbar

CupertinoScrollbar是 iOS 風(fēng)格的滾動(dòng)條,如果你使用的是Scrollbar,那么在iOS平臺它會自動(dòng)切換為CupertinoScrollbar

總結(jié)

本篇介紹了可滾動(dòng)組件的概念和具體的組成,構(gòu)造。后續(xù)會具體介紹一些可滾動(dòng)組件的使用詳解。如ListView,GridView等,更多關(guān)于Flutter 可滾動(dòng)組件的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • iOS 內(nèi)存泄漏排查方法及原因分析

    iOS 內(nèi)存泄漏排查方法及原因分析

    本文主要介紹了iOS 內(nèi)存泄漏排查方法及原因,將從以下兩個(gè)層面解決iOS內(nèi)存泄漏問題,內(nèi)存泄漏排查方法和內(nèi)存泄漏原因分析,文中有詳細(xì)的圖文介紹,需要的朋友可以參考下
    2023-07-07
  • MAC中顯示隱藏文件和不顯示隱藏文件的方法(超簡單)

    MAC中顯示隱藏文件和不顯示隱藏文件的方法(超簡單)

    下面小編就為大家分享一篇MAC中顯示隱藏文件和不顯示隱藏文件的方法(超簡單),具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-01-01
  • 總結(jié)iOS App開發(fā)中控制屏幕旋轉(zhuǎn)的幾種方式

    總結(jié)iOS App開發(fā)中控制屏幕旋轉(zhuǎn)的幾種方式

    這篇文章主要介紹了iOS app開發(fā)中控制屏幕旋轉(zhuǎn)的方法總結(jié),分為自動(dòng)旋轉(zhuǎn)和手動(dòng)旋轉(zhuǎn)以及強(qiáng)制旋轉(zhuǎn)三種情況,代碼為Objective-C語言,需要的朋友可以參考下
    2016-02-02
  • 一篇文章讓你看懂IOS中的block為何再也不需要WeakSelf弱引用

    一篇文章讓你看懂IOS中的block為何再也不需要WeakSelf弱引用

    這篇文章主要給大家介紹了關(guān)于IOS中block為何再也不需要WeakSelf弱引用的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對各位iOS開發(fā)者們具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2018-01-01
  • iOS程序性能優(yōu)化的技巧

    iOS程序性能優(yōu)化的技巧

    這篇文章主要介紹了一些優(yōu)化iOS程序性能的技巧,幫助大家更好的進(jìn)行ios開發(fā),感興趣的朋友可以了解下
    2020-09-09
  • iOS DropDown下拉按鈕效果代碼分享

    iOS DropDown下拉按鈕效果代碼分享

    這篇文章主要為大家詳細(xì)介紹了iOS DropDown下拉按鈕效果的實(shí)現(xiàn)代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-04-04
  • iOS自定義UIScrollView的滾動(dòng)條實(shí)例代碼

    iOS自定義UIScrollView的滾動(dòng)條實(shí)例代碼

    本篇文章主要介紹了iOS自定義UIScrollView的滾動(dòng)條實(shí)例代碼,詳細(xì)的介紹了自定義滾動(dòng)條的示例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。
    2017-03-03
  • iOS mobileconfig配置文件進(jìn)行簽名的配置方法

    iOS mobileconfig配置文件進(jìn)行簽名的配置方法

    這篇文章主要介紹了iOS mobileconfig配置文件進(jìn)行簽名的配置方法,給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-02-02
  • 快速解決ios微信下audio無法自動(dòng)播放的問題

    快速解決ios微信下audio無法自動(dòng)播放的問題

    下面小編就為大家分享一篇快速解決ios微信下audio無法自動(dòng)播放的問題,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-03-03
  • NSMutable?對象的坑解決分析

    NSMutable?對象的坑解決分析

    這篇文章主要為大家介紹了NSMutable?對象的坑解決分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-02-02

最新評論

深水埗区| 黄骅市| 江永县| 南漳县| 天祝| 长白| 拜城县| 桐庐县| 乐清市| 四子王旗| 榆社县| 陵水| 方山县| 巴彦淖尔市| 富平县| 伽师县| 谢通门县| 揭西县| 南华县| 陇川县| 九龙县| 横峰县| 清苑县| 延庆县| 文山县| 洛扎县| 松滋市| 蓬溪县| 高淳县| 英吉沙县| 神池县| 定州市| 册亨县| 襄汾县| 绥宁县| 南陵县| 博野县| 嘉善县| 大竹县| 南郑县| 建瓯市|