一区二区三区三上|欧美在线视频五区|国产午夜无码在线观看视频|亚洲国产裸体网站|无码成年人影视|亚洲AV亚洲AV|成人开心激情五月|欧美性爱内射视频|超碰人人干人人上|一区二区无码三区亚洲人区久久精品

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Flutter 3.3 之 SelectionArea 好不好用?用 "Bug" 帶您全面了解它 | 開發(fā)者說·DTalk

谷歌開發(fā)者 ? 來源:未知 ? 2022-11-10 11:35 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群


本文原作者: 戀貓de小郭,原文發(fā)布于:GSYTech


隨著 Flutter 3.3 正式版發(fā)布,Global Selection 終于有了官方的正式支持,「該功能補(bǔ)全了 Flutter 長時(shí)間存在 Selection 異常等問題,特別是在 Flutter Web 下經(jīng)常會(huì)有選擇文本時(shí)與預(yù)期的行為不匹配的情況」



使用


「使用 SelectionArea 也十分簡單,如下代碼所示,只需要在您想要支持的地方添加 SelectionArea 即可」,甚至可以在每個(gè)路由下的Scaffold 添加SelectionArea 來全面啟用支持。

默認(rèn)情況下SelectionArea 已經(jīng)實(shí)現(xiàn)了所有常見的功能,并且 Flutter 針對(duì)不同平臺(tái)進(jìn)行了差異化實(shí)現(xiàn),如下圖所示 AndroidiOS 會(huì)有不同的樣式效果。





「當(dāng)然,也許這時(shí)候您會(huì)發(fā)現(xiàn)在 iOS 上的 Toolbar 居然沒有全選」,其實(shí)這是因?yàn)?iOS 使用了 TextSelectionControls 默認(rèn)的 canSelectAll 判斷,這個(gè)判斷里有一個(gè)條件就是需要 selection 的 start == end 才符合條件。

所以如果您覺得這個(gè)判斷有問題,完全可以自己 override 一個(gè)自定義的 TextSelectionControls,比如在canSelectAll 直接 return true。





是的,「對(duì)于SelectionArea 我們可以通過繼承 TextSelectionControls 來自定義」:

  • 通過 buildToolbar 自定義彈出的 Toolbar 樣式和邏輯,甚至您可以添加一些額外的標(biāo)簽能力,比如 "插入圖片";
  • 通過 buildHandle 自定義 Selection Handle 可拖動(dòng)部分的樣式。

而在SelectionArea 里,不管是 Handle 還是 Toolbar,都是通過新增 Overlay 來實(shí)現(xiàn)樣式,這部分的邏輯主要在 SelectionOverlay 對(duì)象:






如果您還不了解Overlay,可以簡單理解為:「默認(rèn)情況下所有的路由頁面都在一個(gè) Overlay 下,打開一個(gè) Route 就是添加一個(gè) OverlayEntryOverlay 里」

所以 Handle 和 Toolbar 都是通過OverlayEntry 打開的特殊 "路由" 控件,擁有新的層級(jí),例如下方右圖就是 Toolbar 所在的OverlayEntry。







「另外,對(duì)于 Handle 的顏色定義,默認(rèn)情況下主要來自 TextSelectionThemeTheme。


例如MaterialTextSelectionControls 里,start 和 end 兩個(gè) Handle 的顏色,默認(rèn)是通過 TextSelectionThemeselectionHandleColor 或者Themeprimary 來設(shè)置。

那文字的選中區(qū)域的顏色是怎么來的?難道也是 OverlayEntry 嗎?

答案是否定的,這部分顏色主要是來自于文本繪制時(shí) Canvas 的渲染。

如下代碼所示,「當(dāng)文本被繪制時(shí),會(huì)判斷當(dāng)前是否有被選中的片段,如果存在選中的片段,會(huì)調(diào)用繪制對(duì)應(yīng)的選中圖層」。

而對(duì)于文字的選中區(qū)塊的顏色,默認(rèn)是通過 DefaultSelectionStyleselectionColor 來顯示,當(dāng)然,如下第二張圖所示,在 MaterialApp 里它依然和 TextSelectionThemeselectionColor 或者Themeprimary 有關(guān)系。

「那如果您還想要在SelectionArea 下的某些內(nèi)容不允許被選中呢」


這里 Flutter 提供了 SelectionContainer.disabled 實(shí)現(xiàn),只要在對(duì)應(yīng)內(nèi)容嵌套 SelectionContainer.disabled,那么這部分內(nèi)容下的文本就無法被選中。



為什么嵌套SelectionContainer.disabled 就可以禁用文本選中的能力?這其實(shí)和SelectionArea 的實(shí)現(xiàn)有關(guān)系:


SelectionContainer 內(nèi)部實(shí)現(xiàn)了一個(gè) InheritedWidget,它會(huì)往下共享一個(gè) SelectionRegistrar,而默認(rèn)情況下SelectionArea 內(nèi)部使用了SelectionContainer 并且往下共享了對(duì)應(yīng)的 Registrar 實(shí)現(xiàn)。


  • SelectionArea 內(nèi)部的 SelectionContainer 是有對(duì)應(yīng)的 registrar 實(shí)現(xiàn)往下共享;
  • SelectionContainer.disabled 內(nèi)部的registrarnull。

「所以根本區(qū)別就在于 SelectionContainer.disabled 里沒有 registrar,如下圖一所示,加了 disabled 后獲取到的 registrar 是 null,那么如下圖二代碼所示,在后續(xù)可選中區(qū)域的更新邏輯中就會(huì)直接 return。
△ 圖一

圖二

到這里您應(yīng)該大致理解了如何使用和自定義一些 SelectionArea 的能力,那么接下來介紹兩個(gè) "Bug",通過這兩個(gè) "Bug" 我們深入理解SelectionArea 內(nèi)部的實(shí)現(xiàn)情況。



問題 1


如下代碼所示,「當(dāng)使用了WidgetSpan 之后,默認(rèn)情況下,用戶在開始位置拖拽 Handle 進(jìn)行選擇時(shí)會(huì)無法選中WidgetSpan 里的文本」。





PS:其實(shí)拖動(dòng)可以選中,只是這里暫時(shí)以不能選中的情況下作為切入點(diǎn)。


為什么會(huì)這樣?首先要知道,上面代碼在使用了WidgetSpan 包裹 Hello World 之后,其實(shí)是存在兩個(gè) Text,也就是上述的 UI 是由兩個(gè) RenderParagraph 繪制完成。

那么對(duì)于最外層的 Text,其實(shí)它的文本內(nèi)容是 "Flutter is the best!",注意這段文本,其實(shí)文本里此時(shí)是多了兩個(gè)空格。
之所以會(huì)有這兩個(gè)空格,其實(shí)是因?yàn)?/span>WidgetSpan 使用了 0xFFFC 的占位符,這段占位符在渲染時(shí),就會(huì)被替換為WidgetSpan 對(duì)應(yīng)的 Hello World 和貓頭圖片。

「那么這時(shí)候如果我們選擇復(fù)制,復(fù)制出來的內(nèi)容會(huì)是 Flutter isthe best!,中間的兩個(gè)占位符是不會(huì)復(fù)制出來,因?yàn)樵讷@取可選擇片段時(shí),會(huì)把對(duì)應(yīng)的 placeholderCodeUnit 剔除。

另外,當(dāng)我們點(diǎn)擊復(fù)制的時(shí)候,WidgetSpan 所在的Hello World 并沒有被選中,所以此時(shí)調(diào)用 getSelectedContent 就會(huì)得到 null,也就是沒有內(nèi)容。
所以可以看到: 此時(shí)在手動(dòng)拖拽選擇時(shí),WidgetSpan 里的文本是不會(huì)被選中,因?yàn)樗幱诓煌?Text,對(duì)于外層 Text 而言它只是個(gè)占位符。


當(dāng)然,「其實(shí)在拖動(dòng)Handle還是可以選中WidgetSpan里的文本,比如您從HelloWorld開始拖動(dòng),這里拖動(dòng)選中不了的原因后面會(huì)解釋」。


問題2


如果當(dāng)我們點(diǎn)擊了全選會(huì)怎么樣?如下圖所示,在我們點(diǎn)擊全選之后,可以看到兩個(gè) "奇怪" 的問題:

  • WidgetSpan 里的 Hello World 可以被選中了;
  • 左側(cè)的 Start Handle 位置不是在文本開頭,而是在WidgetSpan 開始。

我們首先看第一點(diǎn),「為什么點(diǎn)擊全選時(shí),WidgetSpan 里的 Hello World 可以被選中」


其實(shí)全選操作和拖拽 Handle 最大的不同就是: 它是往下直接發(fā)出全選事件 SelectAllSelectionEvent,而該事件會(huì)觸發(fā)所有 child 響應(yīng)事件,自然也就包括了 WidgetSpan 里的 Hello World

最后負(fù)責(zé)響應(yīng) SelectAll 事件的對(duì)象是 _SelectableFragment,這里主要有兩個(gè)關(guān)鍵邏輯:
  • _handleSelectAll 獲取得到 _textSelectionStart_textSelectionEnd,表明此時(shí)控件已經(jīng)被選中;
  • didChangeSelection 里通過 paragraph.markNeedsPaint() 觸發(fā)重繪,然后增加選中時(shí)的覆蓋顏色。
可以看到,由于此時(shí) WidgetSpan 里的 Hello World 也直接響應(yīng)了全選事件,所以它會(huì)處于選中狀態(tài),這樣之后在 getSelectedContent 調(diào)用里也可以獲取到內(nèi)容,也就是Hello World 能被復(fù)制出來。
**但是此時(shí)復(fù)制出來的內(nèi)容會(huì)是 Hello World!Flutter isthe best! **,是不是感覺還不對(duì)?這就是我們要說的第二個(gè)問題,左側(cè)的 Start Handle 位置不是在文本開頭。

首先我們看,為什么復(fù)制出來之后的內(nèi)容會(huì)是Hello World!Flutter isthe best!


正如前面說到的,復(fù)制調(diào)用的是 getSelectedContent 方法,如下代碼所示,「可以看到在selectables 這個(gè) List 的第一位就是Hello World,所以最終拼接出來的文本會(huì)是Hello World!Flutter isthe best! 。

那為什么 Hello World 會(huì)排在 selectables 的第一位?這就需要講到 Flutter 里對(duì) Selectable 的一個(gè)排序邏輯。

我們知道 Text 內(nèi)部是通過 RenderParagraph 實(shí)現(xiàn)文本繪制,而RenderParagraph 在初始化的時(shí)候,「如果存在 _registrar,也就是存在SelectionArea 的時(shí)候,就會(huì)通過 add 把支持選中的片段添加 SelectionArea 內(nèi)部的 _additions里。
之后 SelectionArea 內(nèi)部會(huì)對(duì)可選中的內(nèi)容進(jìn)行排序,如下代碼所示,在 sort 之前,此時(shí)的 Hello World_additions 列表的最末端,因?yàn)樗幱?WidgetSpan 的 child 里,所以是最晚被加入到 _additions 的。
而在執(zhí)行完 sort 之后,可以看到此時(shí) Hello World 跑到了列表的最前面,「這也是為什么復(fù)制出來的內(nèi)容順序是Hello World 開頭,然后 Start Handle 會(huì)顯示在Hello World 的原因」。
sort 的邏輯主要是通過compareOrder 實(shí)現(xiàn),簡單分析 compareOrder 的排序?qū)崿F(xiàn),可以看到其中有一個(gè) _compareVertically 的邏輯,通過調(diào)試對(duì)比,「可以看到此時(shí)因?yàn)?/strong>Hello World 所處的 Rect (top) 比其他文本高,所以它被認(rèn)為是更高優(yōu)先級(jí)的位置,類似于被誤認(rèn)為是上一行的情況」。
知道了問題那就很好處理了,「如下代碼所示,如果此時(shí)調(diào)整一下 WidgetSpan 的高度,可以看到全選邏輯下 Start Handle 正常了,但是.... End Handle 位置又不對(duì)了」。





此時(shí)復(fù)制出來的內(nèi)容會(huì)是 Flutter isthe best!Hello World!「因?yàn)檫@個(gè)時(shí)候會(huì)有一個(gè)很 "微妙" 的偏差值,導(dǎo)致 Hello World 排序時(shí)被排列到最后面」,從而導(dǎo)致 End Handle 不是預(yù)期的位置。
另外,這時(shí)候您會(huì)發(fā)現(xiàn),如下左側(cè)動(dòng)圖所示,「此時(shí)拖動(dòng) Handle 是可以選中 WidgetSpan 里的 Hello World,其實(shí)之前的情況下也可以,不過需要如右側(cè)動(dòng)圖所示,需要從Hello World 開始拖動(dòng),「因?yàn)樽铋_始的情況下 selectablesHello World 的排序?qū)蛹?jí)更高,所以如果想要拖動(dòng)選中,也需要從它開始」。





目前這個(gè)問題在 master 和 stable 分支均可以復(fù)現(xiàn),對(duì)應(yīng) issue 我也提交在#111021。


最后


雖然SelectionArea 的出現(xiàn)補(bǔ)全了 Flutter 的長久以來的短板之一,不過基于SelectionArea 實(shí)現(xiàn)的復(fù)雜程度,目前SelectionArea 還有不少的細(xì)節(jié)需要優(yōu)化,但是萬事開頭難,本次 3.3 SelectionArea 的落地也算是一個(gè)不錯(cuò)的開始。


最后,相信通過本文大家應(yīng)該對(duì) SelectionArea 的使用和實(shí)現(xiàn)都有了一定的了解。



長按右側(cè)二維碼

查看更多開發(fā)者精彩分享




"開發(fā)者說·DTalk" 面向中國開發(fā)者們征集 Google 移動(dòng)應(yīng)用 (apps & games)?相關(guān)的產(chǎn)品/技術(shù)內(nèi)容。歡迎大家前來分享您對(duì)移動(dòng)應(yīng)用的行業(yè)洞察或見解、移動(dòng)開發(fā)過程中的心得或新發(fā)現(xiàn)、以及應(yīng)用出海的實(shí)戰(zhàn)經(jīng)驗(yàn)總結(jié)和相關(guān)產(chǎn)品的使用反饋等。我們由衷地希望可以給這些出眾的中國開發(fā)者們提供更好展現(xiàn)自己、充分發(fā)揮自己特長的平臺(tái)。我們將通過大家的技術(shù)內(nèi)容著重選出優(yōu)秀案例進(jìn)行谷歌開發(fā)技術(shù)專家 (GDE)的推薦。



?點(diǎn)擊屏末||即刻報(bào)名參與"開發(fā)者說·DTalk"





原文標(biāo)題:Flutter 3.3 之 SelectionArea 好不好用?用 "Bug" 帶您全面了解它 | 開發(fā)者說·DTalk

文章出處:【微信公眾號(hào):谷歌開發(fā)者】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴
  • 谷歌
    +關(guān)注

    關(guān)注

    27

    文章

    6231

    瀏覽量

    108132

原文標(biāo)題:Flutter 3.3 之 SelectionArea 好不好用?用 "Bug" 帶您全面了解它 | 開發(fā)者說·DTalk

文章出處:【微信號(hào):Google_Developers,微信公眾號(hào):谷歌開發(fā)者】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    阿童木雙張檢測器好不好用?數(shù)據(jù)和場景說話

    在工業(yè)生產(chǎn)中,雙張疊料檢測是保障產(chǎn)線穩(wěn)定與產(chǎn)品質(zhì)量的關(guān)鍵環(huán)節(jié)。阿童木雙張檢測器憑借技術(shù)創(chuàng)新和行業(yè)落地經(jīng)驗(yàn),成為眾多企業(yè)的選擇。但它究竟“好不好用”?本文將從性能表現(xiàn)、場景適配、用戶反饋三大維度展開
    的頭像 發(fā)表于 05-22 11:39 ?244次閱讀
    阿童木雙張檢測器<b class='flag-5'>好不好用</b>?<b class='flag-5'>用</b>數(shù)據(jù)和場景說話

    電子工廠ERP好不好用

    在電子制造業(yè)競爭日益激烈的當(dāng)下,企業(yè)都在尋找提升效率、降低成本的解決方案,而ERP系統(tǒng)成為了眾多企業(yè)的選擇。那么,電子工廠ERP系統(tǒng)到底好不好用呢?本文將從多個(gè)實(shí)際應(yīng)用場景出發(fā),為你揭開答案。一
    的頭像 發(fā)表于 05-12 09:58 ?235次閱讀
    電子工廠ERP<b class='flag-5'>好不好用</b>

    開源mlops平臺(tái)好用

    在MLOps平臺(tái)的選擇上,開源平臺(tái)因其成本效益、靈活性以及社區(qū)支持等優(yōu)勢,受到了越來越多開發(fā)者和企業(yè)的青睞。那么,開源MLOps平臺(tái)真的好用嗎?下面,AI部落小編
    的頭像 發(fā)表于 03-05 11:09 ?339次閱讀

    云端AI開發(fā)者工具的核心功能

    當(dāng)今,云端AI開發(fā)者工具已成為推動(dòng)科技創(chuàng)新與行業(yè)升級(jí)的重要力量。那么,云端AI開發(fā)者工具有哪些核心功能呢?下面,AI部落小編深入探討。
    的頭像 發(fā)表于 02-28 11:46 ?476次閱讀

    國外AI開發(fā)者平臺(tái)好用

    當(dāng)今,AI項(xiàng)目的復(fù)雜性和多變性給項(xiàng)目管理帶來了前所未有的挑戰(zhàn)。為了有效應(yīng)對(duì)這些挑戰(zhàn),AI項(xiàng)目管理平臺(tái)應(yīng)運(yùn)而生。那么,AI項(xiàng)目管理平臺(tái)有什么?下面,AI部落小編了解。
    的頭像 發(fā)表于 02-19 10:16 ?307次閱讀

    AI開發(fā)平臺(tái)如何賦能開發(fā)者

    當(dāng)下,AI開發(fā)平臺(tái)通過提供豐富的工具集、優(yōu)化的開發(fā)環(huán)境以及高效的部署能力,極大地降低了AI應(yīng)用的開發(fā)門檻,加速了創(chuàng)新步伐。那么,AI開發(fā)平臺(tái)如何賦能
    的頭像 發(fā)表于 01-17 14:47 ?407次閱讀

    云端AI開發(fā)者工具怎么

    云端AI開發(fā)者工具通常包括代碼編輯器、模型訓(xùn)練平臺(tái)、自動(dòng)化測試工具、代碼管理工具等。這些工具不僅降低了AI開發(fā)的門檻,還極大地提高了開發(fā)效率和模型性能。下面,AI部落小編為介紹云端A
    的頭像 發(fā)表于 12-05 13:31 ?561次閱讀

    ADS1299EEGFE-PDK如何測量負(fù)反饋信號(hào)?

    您好!我想問一下關(guān)于測量負(fù)反饋信號(hào)的方法 我將JP1如圖連接,希望看看負(fù)反饋電路好不好用,這樣的話我的測試信號(hào)來源和寄存器如何配置
    發(fā)表于 11-20 08:13

    請問class D類運(yùn)放不好用作驅(qū)動(dòng)headphone的原因有哪些?

    請問class D類運(yùn)放不好用作驅(qū)動(dòng)headphone的原因除了EMI問題,還有沒有其它問題的限制,導(dǎo)致TI沒有生產(chǎn)class D的headphone功
    發(fā)表于 11-04 08:06

    鴻蒙Flutter實(shí)戰(zhàn):07混合開發(fā)

    。 其優(yōu)點(diǎn)是主項(xiàng)目開發(fā)者可以不關(guān)注Flutter實(shí)現(xiàn),不需要安裝配置Flutter開發(fā)環(huán)境,缺點(diǎn)是無法及時(shí)修改Flutter代碼,也不存在
    發(fā)表于 10-23 16:00

    KaihongOS 4.1.2開發(fā)者預(yù)覽版正式上線,誠邀開發(fā)者免費(fèi)試用!

    深開鴻在2024開放原子開源生態(tài)大會(huì)上正式宣布KaihongOS4.1.2開發(fā)者預(yù)覽版全面上線,并向全球開發(fā)者開放免費(fèi)下載。作為KaihongOS不斷創(chuàng)新與發(fā)展的重要里程碑,此次預(yù)覽版為開發(fā)者
    的頭像 發(fā)表于 09-28 08:07 ?733次閱讀
    KaihongOS 4.1.2<b class='flag-5'>開發(fā)者</b>預(yù)覽版正式上線,誠邀<b class='flag-5'>開發(fā)者</b>免費(fèi)試用!

    KaihongOS 4.1.2開發(fā)者預(yù)覽版正式上線,誠邀開發(fā)者免費(fèi)試用!

    今日,深開鴻在2024開放原子開源生態(tài)大會(huì)上正式宣布KaihongOS 4.1.2開發(fā)者預(yù)覽版全面上線,并向全球開發(fā)者開放免費(fèi)下載。作為KaihongOS不斷創(chuàng)新與發(fā)展的重要里程碑,此次預(yù)覽版為
    的頭像 發(fā)表于 09-26 15:59 ?744次閱讀

    安規(guī)電容好不好用看這幾點(diǎn)

    安規(guī)電容是保護(hù)電源和電路的電子元件,需通過安規(guī)認(rèn)證和標(biāo)準(zhǔn),保證穩(wěn)定性和可靠性。電氣性能穩(wěn)定,品牌選擇關(guān)鍵。符合標(biāo)準(zhǔn)且品質(zhì)好的安規(guī)電容可確保電子產(chǎn)品正常運(yùn)行,減少事故風(fēng)險(xiǎn)。
    的頭像 發(fā)表于 09-06 16:12 ?780次閱讀
    安規(guī)電容<b class='flag-5'>好不好用</b>看這幾點(diǎn)

    安規(guī)電容好不好用看這幾點(diǎn)

    安規(guī)電容是保護(hù)電源和電路的電子元件,需通過安規(guī)認(rèn)證和標(biāo)準(zhǔn),保證穩(wěn)定性和可靠性。電氣性能穩(wěn)定,品牌選擇關(guān)鍵。符合標(biāo)準(zhǔn)且品質(zhì)好的安規(guī)電容可確保電子產(chǎn)品正常運(yùn)行,減少事故風(fēng)險(xiǎn)。
    的頭像 發(fā)表于 09-06 16:12 ?561次閱讀

    OPA544芯片的黑色主體材料導(dǎo)熱性好不好?

    銅區(qū)域是無法滿足散熱要求的。請問有沒有其他的散熱方式?在OPA544芯片的上表面(標(biāo)記信號(hào)的面)導(dǎo)熱硅膠粘上散熱片的方式可不可行?OPA544芯片的黑色主體材料導(dǎo)熱性好不好
    發(fā)表于 08-22 06:37