flutter畫(huà)虛線,fluidsim虛線怎么畫(huà)

Flutter 啟動(dòng)頁(yè)的前世今生適配歷程

APP 啟動(dòng)頁(yè)在國(guó)內(nèi)是最常見(jiàn)也是必備的場(chǎng)景,其中啟動(dòng)頁(yè)在 iOS 上算是強(qiáng)制性的要求,其實(shí)配置啟動(dòng)頁(yè)挺簡(jiǎn)單,因?yàn)樵?Flutter 里現(xiàn)在只需要:

為海門(mén)等地區(qū)用戶提供了全套網(wǎng)頁(yè)設(shè)計(jì)制作服務(wù),及海門(mén)網(wǎng)站建設(shè)行業(yè)解決方案。主營(yíng)業(yè)務(wù)為網(wǎng)站建設(shè)、成都網(wǎng)站設(shè)計(jì)、海門(mén)網(wǎng)站設(shè)計(jì),以傳統(tǒng)方式定制建設(shè)網(wǎng)站,并提供域名空間備案等一條龍服務(wù),秉承以專業(yè)、用心的態(tài)度為用戶提供真誠(chéng)的服務(wù)。我們深信只要達(dá)到每一位用戶的要求,就會(huì)得到認(rèn)可,從而選擇與我們長(zhǎng)期合作。這樣,我們也可以走得更遠(yuǎn)!

一般只要配置無(wú)誤并且圖片尺寸匹配,基本上就不會(huì)有什么問(wèn)題, 那既然這樣,還有什么需要適配的呢?

事實(shí)上大部分時(shí)候 iOS 是不會(huì)有什么問(wèn)題, 因?yàn)? LaunchScreen.storyboard 的流程本就是 iOS 官方用來(lái)做應(yīng)用啟動(dòng)的過(guò)渡;而對(duì)于 Andorid 而言,直到 12 之前 windowBackground 這種其實(shí)只能算“民間”野路子 ,所以對(duì)于 Andorid 來(lái)說(shuō),這其中就涉及到一個(gè)點(diǎn):

所以下面主要介紹 Flutter 在 Android 上為了這個(gè)啟動(dòng)圖做了哪些騷操作~

在已經(jīng)忘記版本的“遠(yuǎn)古時(shí)期” , FlutterActivity 還在 io.flutter.app.FlutterActivity 路徑下的時(shí)候,那時(shí)啟動(dòng)頁(yè)的邏輯相對(duì)簡(jiǎn)單,主要是通過(guò) App 的 AndroidManifest 文件里是否配置了 SplashScreenUntilFirstFrame 來(lái)進(jìn)行判斷。

在 FlutterActivity 內(nèi)部 FlutterView 被創(chuàng)建的時(shí)候,會(huì)通過(guò)讀取 meta-data 來(lái)判斷是否需要使用 createLaunchView 邏輯 :

是不是很簡(jiǎn)單,那就會(huì)有人疑問(wèn)為什么要這樣做?我直接配置 Activity 的 android:windowBackground 不就完成了嗎?

這就是上面提到的時(shí)間差問(wèn)題, 因?yàn)閱?dòng)頁(yè)到 Flutter 渲染完第一幀畫(huà)面中間,會(huì)出現(xiàn)概率出現(xiàn)黑屏的情況,所以才需要這個(gè)行為來(lái)實(shí)現(xiàn)過(guò)渡 。

經(jīng)歷了“遠(yuǎn)古時(shí)代”之后, FlutterActivity 來(lái)到了 io.flutter.embedding.android.FlutterActivity , 在到 2.5 版本發(fā)布之前,F(xiàn)lutter 又針對(duì)這個(gè)啟動(dòng)過(guò)程做了不少調(diào)整和優(yōu)化,其中主要就是 SplashScreen 。

自從開(kāi)始進(jìn)入 embedding 階段后, FlutterActivity 主要用于實(shí)現(xiàn)了一個(gè)叫 Host 的 interface ,其中和我們有關(guān)系的就是 provideSplashScreen 。

默認(rèn)情況下它會(huì)從 AndroidManifest 文件里是否配置了 SplashScreenDrawable 來(lái)進(jìn)行判斷 。

默認(rèn)情況下當(dāng) AndroidManifest 文件里配置了 SplashScreenDrawable ,那么這個(gè) Drawable 就會(huì)在 FlutterActivity 創(chuàng)建 FlutterView 時(shí)被構(gòu)建成 DrawableSplashScreen 。

DrawableSplashScreen 其實(shí)就是一個(gè)實(shí)現(xiàn)了 io.flutter.embedding.android.SplashScreen 接口的類,它的作用就是:

之后 FlutterActivity 內(nèi)會(huì)創(chuàng)建出 FlutterSplashView ,它是個(gè) FrameLayout。

FlutterSplashView 將 FlutterView 和 ImageView 添加到一起, 然后通過(guò) transitionToFlutter 的方法來(lái)執(zhí)行動(dòng)畫(huà),最后動(dòng)畫(huà)結(jié)束時(shí)通過(guò) onTransitionComplete 移除 splashScreenView 。

所以整體邏輯就是:

當(dāng)然這里也是分狀態(tài):

當(dāng)然這個(gè)階段的 FlutterActivity 也可以通過(guò) override provideSplashScreen 方法來(lái)自定義 SplashScreen 。

看到?jīng)]有,做了這么多其實(shí)也就是為了彌補(bǔ)啟動(dòng)頁(yè)和 Flutter 渲染之間, 另外還有一個(gè)優(yōu)化,叫 NormalTheme 。

通過(guò)該配置 NormalTheme ,在 Activity 啟動(dòng)時(shí),就會(huì)首先執(zhí)行 switchLaunchThemeForNormalTheme(); 方法將主題從 LaunchTheme 切換到 NormalTheme 。

大概配置完就是如下樣子, 前面分析那么多其實(shí)就是為了告訴你,如果出現(xiàn)問(wèn)題了,你可以從哪個(gè)地方去找到對(duì)應(yīng)的點(diǎn) 。

講了那么多, Flutter 2.5 之后 provideSplashScreen 和 io.flutter.embedding.android.SplashScreenDrawable 就被棄用了,驚不喜驚喜,意不意外,開(kāi)不開(kāi)心 ?

通過(guò)源碼你會(huì)發(fā)現(xiàn),當(dāng)你設(shè)置了 splashScreen 的時(shí)候,會(huì)看到一個(gè) log 警告:

為什么會(huì)棄用?

其實(shí)這個(gè)提議是在 這個(gè) issue 上,然后通過(guò) 這個(gè) pr 完成調(diào)整。

大概意思就是: 原本的設(shè)計(jì)搞復(fù)雜了,用 OnPreDrawListener 更精準(zhǔn),而且不需要為了后面 Andorid12 的啟動(dòng)支持做其他兼容,只需要給 FlutterActivity 等類增加接口開(kāi)關(guān)即可 。

也就是2.5之后 Flutter 使用 ViewTreeObserver.OnPreDrawListener 來(lái)實(shí)現(xiàn)延遲直到加載出 Flutter 的第一幀。

為什么說(shuō)默認(rèn)情況? 因?yàn)檫@個(gè)行為在 FlutterActivity 里,是在 getRenderMode() == RenderMode.surface 才會(huì)被調(diào)用,而 RenderMode 又和 BackgroundMode 有關(guān)心 。

所以在 2.5 版本后, FlutterActivity 內(nèi)部創(chuàng)建完 FlutterView 后就會(huì)執(zhí)行一個(gè) delayFirstAndroidViewDraw 的操作。

這里主要注意一個(gè)參數(shù): isFlutterUiDisplayed 。

當(dāng) Flutter 被完成展示的時(shí)候, isFlutterUiDisplayed 就會(huì)被設(shè)置為 true。

所以當(dāng) Flutter 沒(méi)有執(zhí)行完成之前, FlutterView 的 onPreDraw 就會(huì)一直返回 false ,這也是 Flutter 2.5 開(kāi)始之后適配啟動(dòng)頁(yè)的新調(diào)整。

看了這么多,大概可以看到其實(shí)開(kāi)源項(xiàng)目的推進(jìn)并不是一帆風(fēng)順的,沒(méi)有什么是一開(kāi)始就是最優(yōu)解,而是經(jīng)過(guò)多方嘗試和交流,才有了現(xiàn)在的版本,事實(shí)上開(kāi)源項(xiàng)目里,類似這樣的經(jīng)歷數(shù)不勝數(shù):

Flutter CustomPaint 使用介紹

CustomPaint class提供了讓用戶自定義widget的能力,它暴露了一個(gè)canvas,可以通過(guò)這個(gè)canvas來(lái)繪制widget,CustomPaint會(huì)先調(diào)用painter繪制背景,然后再繪制child,最后調(diào)用foregroundPainter來(lái)繪制前景,CustomPaint的定義如下

CustomPaint的繪制過(guò)程都將會(huì)交給CustomPainter來(lái)完成,CustomPainter是個(gè)抽象接口,在子類化CustomPainter的時(shí)候必須要重寫(xiě)它的 paint 跟 shouldRepaint 接口,可以根據(jù)自己的場(chǎng)景來(lái)選擇性的重寫(xiě) hitTest 跟 shouldRebuildSemantics 方法。

canvas--畫(huà)布,真正的繪制是由canvas跟paint來(lái)完成的,畫(huà)布提供了各種繪制的接口來(lái)繪制圖形,除此以外畫(huà)布還提供了平移、縮放、旋轉(zhuǎn)等矩陣變換接口,畫(huà)布都有固定大小跟形狀,還可以使用畫(huà)布提供的裁剪接口來(lái)裁剪畫(huà)布的大小形狀等等。

常用的繪制接口有 更多請(qǐng)查看官方文檔

Paint---筆畫(huà),是用來(lái)設(shè)置在畫(huà)布上面繪制圖形時(shí)的一些筆畫(huà)屬性,如:顏色、線寬、繪制模式、抗鋸齒等等。常用屬性有 更多請(qǐng)查看官方文檔

color : 設(shè)置畫(huà)筆顏色

isAntiAlias : 設(shè)置畫(huà)筆是否扛鋸齒

shader : 著色器,填充形狀或者畫(huà)線時(shí)用到,如果沒(méi)設(shè)置將會(huì)使用color

strokeWidth : 設(shè)置畫(huà)筆畫(huà)線寬度

style :繪制模式,畫(huà)線或充滿

下面這個(gè)例子來(lái)自于官方,通過(guò) CustomPaint 畫(huà)出了一個(gè)藍(lán)天跟太陽(yáng)出來(lái)

效果如下:

Flutter自定義繪制組件

Flutter中自定義組件一般有兩種方式:

CustomPaint繼承自SingleChildRenderObjectWidget,即它可以在通過(guò)嵌套引入到widget樹(shù)中,并且可以有一個(gè)child子widget。它的構(gòu)造方法如下:

painter和foregroundPainter需要接收CustomPainter對(duì)象,是CustomPaint核心。CustomPainter是進(jìn)行UI繪制的核心類,繪制時(shí), CustomPaint 首先在畫(huà)布上調(diào)用 painter繪制 , 然后再繪制它的 child Widget, child 繪制完成后再調(diào)用 foregroundPainter 進(jìn)行繪制。

size屬性標(biāo)識(shí)繪制區(qū)域大小,但當(dāng)CustomPaint有child,該屬性將會(huì)忽略,而使用child的大小為繪制區(qū)域大小。

isComplex和willChange用于控制繪制層緩存處理的,這里暫不討論。

可實(shí)現(xiàn)CustomPainter子類進(jìn)行UI繪制

實(shí)現(xiàn)paint方法進(jìn)行真正的繪制,canvas是畫(huà)布對(duì)象,size是繪制區(qū)域,是從CustomPaint中size屬性傳遞得到的。繪制過(guò)程與Android原生開(kāi)發(fā)十分類似,連API都十分相像,這點(diǎn)對(duì)熟悉Android原生開(kāi)發(fā)者真是太友好了。

Paint對(duì)象是畫(huà)筆對(duì)象,就是繪圖工具,我們可以設(shè)置畫(huà)筆的顏色、粗細(xì)、是否抗鋸齒、筆觸形狀以及作畫(huà)風(fēng)格等,通過(guò)這些屬性我們可以很方便的來(lái)定制自己的UI效果,在繪制的過(guò)程中可以定義多個(gè)畫(huà)筆,以便實(shí)現(xiàn)多種風(fēng)格圖形的集合。

根據(jù)需求選擇合適的畫(huà)筆屬性,完成你的繪制。

Canvas是繪制的畫(huà)布,它包含了很多繪制方法,可以繪制出各種形狀的圖形。需要注意的是,畫(huà)布是應(yīng)用所有控件都在使用的, 所以通過(guò)這個(gè)畫(huà)布其實(shí)是可以繪制充滿屏幕的內(nèi)容的,每次繪制都應(yīng)該限制在本控件的區(qū)域(Size)內(nèi), 以免繪制覆蓋到其他組件。

下面介紹下Canvas的繪制方法:

PointMode是個(gè)枚舉

p1、p2為線段兩個(gè)端點(diǎn)

Rect定義矩形的大小位置,有多種構(gòu)造方式:

RRect描述圓角矩形,他通過(guò)Rect和Radius來(lái)構(gòu)造

畫(huà)圓比較簡(jiǎn)單,c表示圓心位置,radius是半徑。

橢圓使用外接矩形確定大小位置,rect就是外接矩形。

繪制弧形,先確定弧形對(duì)應(yīng)的橢圓,同樣地用外接矩形rect確定橢圓,然后根據(jù)起始點(diǎn)和結(jié)束點(diǎn)角度來(lái)確定那一段弧度,startAngle,sweepAngle分別代表起始和結(jié)束點(diǎn)角度,角度用弧度表示法。

useCenter表示是否連接閉合形狀,userCenter = false表示不閉合,即畫(huà)一段弧線,userCenter = true表示閉合,即繪制一個(gè)扇形。

繪制路徑,關(guān)鍵在于構(gòu)建路徑Path,可以直接new Path對(duì)象,然后通過(guò)path方法可以連接出圖形,path關(guān)鍵方法如下:

還有其他方法,有興趣可以查看API。

Flutter-Text文本組件

在開(kāi)發(fā)中,文本是我們最常接觸的控件。這篇博客來(lái)分享一下 Flutter 中的 Text 文本組件,我們展示的文本都可以用這個(gè)組件來(lái)展示,希望看文章的小伙伴有所幫助。

這樣我們就可以在界面當(dāng)中顯示一個(gè)文本,顯示是 Hello Flutter 。下面我們來(lái)說(shuō)說(shuō) Text 組件的屬性:

設(shè)置文本顏色:

設(shè)置文本大?。?/p>

設(shè)置文本樣式-加粗:

設(shè)置文本樣式-斜體:

設(shè)置文本位置:

TextAlign可選屬性: center 、 end 、 start 、 justify 、 left 、 right 。

設(shè)置文本高度:

設(shè)置文本最大行數(shù):

設(shè)置文本有下劃線:

設(shè)置文本有虛線類型下劃線:

設(shè)置文字間隔:

文本超過(guò)最大行數(shù)設(shè)置 ... :

Flutter開(kāi)發(fā)--視頻播放器

目前Flutter平臺(tái)主流的兩個(gè)播放器是video_player和fijkplayer

pub

github

1、Flutter平臺(tái)官方插件,作者是國(guó)外的,有問(wèn)題溝通比較困難,只能通過(guò)提交issue

2、硬解碼

4、UI封裝: better_player

基于video_player和Chewie的高級(jí)視頻播放器。它解決了許多典型的用例,并且易于運(yùn)行。

5、播放器寬高比例與視頻內(nèi)容寬高比例不一致時(shí),會(huì)出現(xiàn)圖像壓縮變形的問(wèn)題

6、調(diào)用原生內(nèi)核播放器:iOS--AVPlayer, Android--ExoPlayer

7、對(duì)于分段源 m3u8 的播放不友好,如果一個(gè)切片播放超時(shí),會(huì)導(dǎo)致整個(gè)播放都失敗

8、better_player可以緩存視頻,但不能自定義緩存的地址,只能指定key,和緩存的最大內(nèi)存量(還未研究超出最大的話是不能緩存新的,還是刪除最舊的)

9、better_player不能完全自定義UI,只能修改類中的一些開(kāi)放屬性,比如說(shuō)icon圖標(biāo),文字顏色啥的

10、無(wú)網(wǎng)絡(luò)有緩存時(shí),封面可以正常展示

11、better_player播放失敗有手動(dòng)retry的設(shè)計(jì)

pub

github

1、fijkplayer 是一個(gè) Flutter 生態(tài)的媒體播放器,是對(duì) ijkplayer 的 Flutter 封裝,支持 Android 和 iOS。 fijkplayer 使用 ijkplayer 作為播放器內(nèi)核,ijkplayer 使用 ffmpeg 進(jìn)行音視頻解封裝和解碼,同時(shí)添加了 Android 和 iOS 平臺(tái)特有的硬件加速解碼能力。

2 、國(guó)內(nèi)有QQ群,但是活躍度也是不高。

3、可以緩存視頻,可以自定義緩存的地址,方便后續(xù)的內(nèi)存維護(hù)。

4、可以通過(guò)FijkPanelWidgetBuilder較大程度上自定義UI。

5、無(wú)網(wǎng)絡(luò)有緩存視頻時(shí),無(wú)法展示封面,因?yàn)閮?nèi)部是通過(guò)imageProvider去加載網(wǎng)絡(luò)圖片的。

7、播放失敗無(wú)手動(dòng)retry的設(shè)計(jì)

1、兩種播放器都是通過(guò)外接紋理方案 (Texture),將播放器視頻畫(huà)面渲染接入 flutter 中,性能上優(yōu)于 PlatformView 的接入方法。

如何自己實(shí)現(xiàn)?

下面以video_palyer的iOS源碼部分解釋:

iOS用CVPixelBufferRef將渲染出來(lái)的數(shù)據(jù)存在內(nèi)存中,F(xiàn)lutter engine會(huì)將Texture的數(shù)據(jù)在內(nèi)存中直接進(jìn)行映射無(wú)需通過(guò)Channel傳輸,然后Texture Widget就可以把你提供的這些數(shù)據(jù)顯示出來(lái)。在我們傳輸數(shù)據(jù)的時(shí)候會(huì)需要將其與 TextureID 綁定,綁定的過(guò)程通過(guò)BasicMessageChannel實(shí)現(xiàn)數(shù)據(jù)流的傳輸,以做到實(shí)時(shí)展示的效果

flutter貝塞爾曲線

1.要繪制貝塞爾線,我們需要四個(gè)點(diǎn): 起點(diǎn) , 終點(diǎn) 和 兩個(gè)控制點(diǎn) ,如下圖所示。移動(dòng)控制點(diǎn)會(huì)改變曲線的斜率。您可以在此 在線工具中 使用控制點(diǎn)。

我們可以使用類Path的cubicTo方法繪制貝塞爾曲線:

使用控制點(diǎn)(x1,y1)和(x2,y2)添加從當(dāng)前點(diǎn)到給定點(diǎn)(x3,y3)的曲線的三次貝塞爾曲線段。

如您所見(jiàn),該cubicTo方法接受三個(gè)參數(shù)。其中兩個(gè)是控制點(diǎn),最后一個(gè)參數(shù)是終點(diǎn)。起點(diǎn)是您的筆已經(jīng)位于畫(huà)布上的位置。

不要忘記在畫(huà)布坐標(biāo)中,左上角是(0,0)點(diǎn),右下角是(size.width,size.height)。因此,請(qǐng)嘗試相應(yīng)地調(diào)整四點(diǎn):

請(qǐng)記住,paint對(duì)象就像我們的筆,我們將其顏色設(shè)置為藍(lán)色,寬度設(shè)置為3。

我們用path對(duì)象描述了bezier路徑。該moveTo方法已用于將筆移動(dòng)到路徑的起點(diǎn)。然后我們調(diào)用cubicTo方法來(lái)定義控制點(diǎn)和終點(diǎn)。之后,我們使用該drawPath方法繪制了路徑。

貝塞爾曲線參考:

///推薦一些曲線圖/折線圖/柱狀圖參考:

all first_rank_v2~rank_v25-2-95632571.nonecaseutm_term=flutter%20%E5%8A%A8%E6%80%81%E7%BB%98%E5%88%B6%E6%9B%B2%E7%BA%BF

名稱欄目:flutter畫(huà)虛線,fluidsim虛線怎么畫(huà)
網(wǎng)站URL:http://muchs.cn/article48/pheiep.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站導(dǎo)航、網(wǎng)站收錄、微信小程序、靜態(tài)網(wǎng)站、移動(dòng)網(wǎng)站建設(shè)、網(wǎng)站設(shè)計(jì)公司

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

營(yíng)銷型網(wǎng)站建設(shè)