中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

商城網(wǎng)站建設(shè)運營合同天津優(yōu)化公司哪家好

商城網(wǎng)站建設(shè)運營合同,天津優(yōu)化公司哪家好,在那可以做公司網(wǎng)站,用什么工具可以創(chuàng)建網(wǎng)頁關(guān)于Flutter Sliver組件內(nèi)容可以參考下面這位博主博客,寫的已經(jīng)非常好了,這里就不再贅述。 38、Flutter之 可滾動組件簡介_flutter 可滑動_風(fēng)雨「83」的博客-CSDN博客 通過閱讀上面的博客,我們已經(jīng)知道了Scrollable和Viewport基礎(chǔ)概念&#…

關(guān)于Flutter Sliver組件內(nèi)容可以參考下面這位博主博客,寫的已經(jīng)非常好了,這里就不再贅述。

38、Flutter之 可滾動組件簡介_flutter 可滑動_風(fēng)雨「83」的博客-CSDN博客

通過閱讀上面的博客,我們已經(jīng)知道了Scrollable和Viewport基礎(chǔ)概念,接下來跟隨作者一起,結(jié)合Flutter源碼分析下ViewPort是如何滾動。

先看一個簡單的demo

MaterialApp(home: Scaffold(body: Center(child: Container(height: 300,child: Scrollable(viewportBuilder: (BuildContext context, ViewportOffset position) {return Viewport(offset: position,slivers: [SliverToBoxAdapter(child: Container(width: 100,height: 100,color: Colors.lightBlue,),),SliverToBoxAdapter(child: Container(width: 100,height: 100,color: Colors.pink,),),SliverToBoxAdapter(child: Container(width: 100,height: 100,color: Colors.green,),),SliverToBoxAdapter(child: Container(width: 100,height: 100,color: Colors.black,),),SliverToBoxAdapter(child: Container(width: 100,height: 100,color: Colors.red,),)],);},))),),)

就是一個簡單的滾動列表,可以上下滾動。

?上面是一個簡單的滾動列表,當(dāng)手指觸摸屏幕時,內(nèi)容隨之發(fā)上移動(滾動)。

下面我們從Flutter刷新機制來梳理下列表里面的組件是在什么時機,由誰觸發(fā)重新布局的(組件的位移就是重新布局的體現(xiàn))。

class Viewport extends MultiChildRenderObjectWidget {......@overrideRenderViewport createRenderObject(BuildContext context) {return RenderViewport(axisDirection: axisDirection,crossAxisDirection: crossAxisDirection ?? Viewport.getDefaultCrossAxisDirection(context, axisDirection),anchor: anchor,offset: offset,cacheExtent: cacheExtent,cacheExtentStyle: cacheExtentStyle,clipBehavior: clipBehavior,);}@overridevoid updateRenderObject(BuildContext context, RenderViewport renderObject) {renderObject..axisDirection = axisDirection..crossAxisDirection = crossAxisDirection ?? Viewport.getDefaultCrossAxisDirection(context, axisDirection)..anchor = anchor..offset = offset..cacheExtent = cacheExtent..cacheExtentStyle = cacheExtentStyle..clipBehavior = clipBehavior;}

Viewport 繼承MultiChildRenderObjectWidget,與之對應(yīng)的RenderObject是RenderViewport,相關(guān)布局邏輯肯定是在RenderViewport 內(nèi)部實現(xiàn)。

class RenderViewport extends RenderViewportBase<SliverPhysicalContainerParentData> {RenderViewport({super.axisDirection,required super.crossAxisDirection,required super.offset,double anchor = 0.0,List<RenderSliver>? children,RenderSliver? center,super.cacheExtent,super.cacheExtentStyle,super.clipBehavior,})

這里我們重點關(guān)注offset這個參數(shù)(其他參數(shù)不是本篇內(nèi)容考慮的范圍),這個參數(shù)在剛剛Viewport 里面賦值,這個參數(shù)是重點,后面會用到。

我們知道RenderViewport管理一個List<RenderSliver> 列表,列表內(nèi)容滾動就是該父組件對子組件列表重新布局的結(jié)果,我們直接找到其performLayou方法

  @overridevoid performLayout() {......int count = 0;do {assert(offset.pixels != null);correction = _attemptLayout(mainAxisExtent, crossAxisExtent, offset.pixels + centerOffsetAdjustment);if (correction != 0.0) {offset.correctBy(correction);} else {if (offset.applyContentDimensions(math.min(0.0, _minScrollExtent + mainAxisExtent * anchor),math.max(0.0, _maxScrollExtent - mainAxisExtent * (1.0 - anchor)),)) {break;}}count += 1;} while (count < _maxLayoutCycles);......}());}

performLayout方法中?

correction = _attemptLayout(mainAxisExtent, crossAxisExtent, offset.pixels + centerOffsetAdjustment);

是我們關(guān)注的重點。

  double _attemptLayout(double mainAxisExtent, double crossAxisExtent, double correctedOffset) {......// positive scroll offsetsreturn layoutChildSequence(child: center,scrollOffset: math.max(0.0, -centerOffset),overlap: leadingNegativeChild == null ? math.min(0.0, -centerOffset) : 0.0,layoutOffset: centerOffset >= mainAxisExtent ? centerOffset: reverseDirectionRemainingPaintExtent,remainingPaintExtent: forwardDirectionRemainingPaintExtent,mainAxisExtent: mainAxisExtent,crossAxisExtent: crossAxisExtent,growthDirection: GrowthDirection.forward,advance: childAfter,remainingCacheExtent: forwardDirectionRemainingCacheExtent,cacheOrigin: clampDouble(centerOffset, -_calculatedCacheExtent!, 0.0),);}

我們找到了layoutChildSequence方法,從方法名就能知道,這個方法功能就是對子組件列表按照順序重新布局的。

  @protecteddouble layoutChildSequence({required RenderSliver? child,required double scrollOffset,required double overlap,required double layoutOffset,required double remainingPaintExtent,required double mainAxisExtent,required double crossAxisExtent,required GrowthDirection growthDirection,required RenderSliver? Function(RenderSliver child) advance,required double remainingCacheExtent,required double cacheOrigin,}) {......while (child != null) {......child.layout(SliverConstraints(axisDirection: axisDirection,growthDirection: growthDirection,userScrollDirection: adjustedUserScrollDirection,scrollOffset: sliverScrollOffset,precedingScrollExtent: precedingScrollExtent,overlap: maxPaintOffset - layoutOffset,remainingPaintExtent: math.max(0.0, remainingPaintExtent - layoutOffset + initialLayoutOffset),crossAxisExtent: crossAxisExtent,crossAxisDirection: crossAxisDirection,viewportMainAxisExtent: mainAxisExtent,remainingCacheExtent: math.max(0.0, remainingCacheExtent + cacheExtentCorrection),cacheOrigin: correctedCacheOrigin,), parentUsesSize: true);......// move on to the next childchild = advance(child);}// we made it without a correction, whee!return 0.0;}

?這個方法就是在不停循環(huán)獲取下一個child,直到最后一個需要布局的child組件。

大體流程就是這樣的,細(xì)心的你一定發(fā)現(xiàn),上面沒有說明組件是如何根據(jù)手指滑動滾動的,也就是如何觸發(fā)RenderViewport 執(zhí)行performLayout方法。

不要急,下面就來說明這一點。

還記得上面提到的offset這個參數(shù)嗎?重頭戲就是它。

  set offset(ViewportOffset value) {assert(value != null);if (value == _offset) {return;}if (attached) {_offset.removeListener(markNeedsLayout);}_offset = value;if (attached) {_offset.addListener(markNeedsLayout);}// We need to go through layout even if the new offset has the same pixels// value as the old offset so that we will apply our viewport and content// dimensions.markNeedsLayout();}

當(dāng)上面我們給RenderViewport 配置offset參數(shù)是,offset是一個ChangeNotifer ,可以添加變化監(jiān)聽

abstract class ViewportOffset extends ChangeNotifier {/// Default constructor.////// Allows subclasses to construct this object directly.ViewportOffset();
......
}

當(dāng)offset 只有的變量更新后,通知監(jiān)聽它的回調(diào)函數(shù)markNeedsLayout,這里就回到了Flutter組件渲染大流程里面了。

這個流程下來是不是非常巧妙,希望大家閱讀完后,也能寫出如此巧妙的架構(gòu)。

http://www.risenshineclean.com/news/30440.html

相關(guān)文章:

  • 門戶網(wǎng)站建設(shè)ppt方案seo公司費用
  • 工作室怎么網(wǎng)站備案外貿(mào)網(wǎng)站推廣平臺有哪些
  • 鄭州高新區(qū)做網(wǎng)站開發(fā)的公司網(wǎng)站seo推廣排名
  • 電子商務(wù)網(wǎng)站建設(shè)總結(jié)免費網(wǎng)站在線觀看人數(shù)在哪直播
  • 網(wǎng)站地圖對seo的影響品牌營銷策劃與管理
  • 做pc端網(wǎng)站平臺今日頭條熱點新聞
  • 建筑網(wǎng)片的用途seo優(yōu)化工具
  • 沌口網(wǎng)站建設(shè)淘寶seo搜索排名優(yōu)化
  • wordpress主頁底端添加圖常州網(wǎng)站seo
  • 公司網(wǎng)站可以自己做河南關(guān)鍵詞排名顧問
  • 網(wǎng)站建設(shè)文案有趣網(wǎng)站關(guān)鍵詞快速排名服務(wù)
  • 網(wǎng)站備案最快多久seo學(xué)院培訓(xùn)班
  • 上傳網(wǎng)站怎么安裝寧德市蕉城區(qū)疫情
  • wordpress隱藏回復(fù)插件seo做關(guān)鍵詞怎么收費的
  • 網(wǎng)站發(fā)外鏈中山seo排名
  • 四川移動網(wǎng)站建設(shè)怎樣做推廣是免費的
  • 網(wǎng)頁界面設(shè)計系統(tǒng)seo描述是什么
  • 網(wǎng)頁設(shè)計軟件adobe鄭州seo技術(shù)顧問
  • ui設(shè)計培訓(xùn)需要多少費用百度關(guān)鍵詞搜索優(yōu)化
  • 織夢網(wǎng)站動態(tài)網(wǎng)站建設(shè)推廣優(yōu)化
  • 老鷹畫室網(wǎng)站哪家做的b站視頻怎么快速推廣
  • 建網(wǎng)站怎么分類亞馬遜關(guān)鍵詞搜索器
  • 吳江做網(wǎng)站建站abc官方網(wǎng)站
  • 佛山外貿(mào)型網(wǎng)站如何做好一個網(wǎng)站
  • 網(wǎng)站知識介紹杭州網(wǎng)站建設(shè)
  • 百度網(wǎng)站托管網(wǎng)站統(tǒng)計哪個好用
  • 淘寶上買衣服的網(wǎng)站湖南企業(yè)seo優(yōu)化首選
  • 手機端網(wǎng)站做app阿里巴巴怎么優(yōu)化關(guān)鍵詞排名
  • 中小企業(yè)融資服務(wù)平臺專業(yè)seo整站優(yōu)化
  • 網(wǎng)站的優(yōu)化承諾上海最新新聞熱點事件