色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

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

谷歌開發者 ? 來源:未知 ? 2022-11-10 11:35 ? 次閱讀


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


隨著 Flutter 3.3 正式版發布,Global Selection 終于有了官方的正式支持,「該功能補全了 Flutter 長時間存在 Selection 異常等問題,特別是在 Flutter Web 下經常會有選擇文本時與預期的行為不匹配的情況」。



使用


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

默認情況下SelectionArea 已經實現了所有常見的功能,并且 Flutter 針對不同平臺進行了差異化實現,如下圖所示 AndroidiOS 會有不同的樣式效果。





「當然,也許這時候您會發現在 iOS 上的 Toolbar 居然沒有全選」,其實這是因為 iOS 使用了 TextSelectionControls 默認的 canSelectAll 判斷,這個判斷里有一個條件就是需要 selection 的 start == end 才符合條件。

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





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

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

而在SelectionArea 里,不管是 Handle 還是 Toolbar,都是通過新增 Overlay 來實現樣式,這部分的邏輯主要在 SelectionOverlay 對象:






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

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







「另外,對于 Handle 的顏色定義,默認情況下主要來自 TextSelectionThemeTheme。


例如MaterialTextSelectionControls 里,start 和 end 兩個 Handle 的顏色,默認是通過 TextSelectionThemeselectionHandleColor 或者Themeprimary 來設置。

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

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

如下代碼所示,「當文本被繪制時,會判斷當前是否有被選中的片段,如果存在選中的片段,會調用繪制對應的選中圖層」

而對于文字的選中區塊的顏色,默認是通過 DefaultSelectionStyleselectionColor 來顯示,當然,如下第二張圖所示,在 MaterialApp 里它依然和 TextSelectionThemeselectionColor 或者Themeprimary 有關系。

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


這里 Flutter 提供了 SelectionContainer.disabled 實現,只要在對應內容嵌套 SelectionContainer.disabled,那么這部分內容下的文本就無法被選中。



為什么嵌套SelectionContainer.disabled 就可以禁用文本選中的能力?這其實和SelectionArea 的實現有關系:


SelectionContainer 內部實現了一個 InheritedWidget,它會往下共享一個 SelectionRegistrar,而默認情況下SelectionArea 內部使用了SelectionContainer 并且往下共享了對應的 Registrar 實現。


  • SelectionArea 內部的 SelectionContainer 是有對應的 registrar 實現往下共享;
  • SelectionContainer.disabled 內部的registrarnull

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

圖二

到這里您應該大致理解了如何使用和自定義一些 SelectionArea 的能力,那么接下來介紹兩個 "Bug",通過這兩個 "Bug" 我們深入理解SelectionArea 內部的實現情況。



問題 1


如下代碼所示,「當使用了WidgetSpan 之后,默認情況下,用戶在開始位置拖拽 Handle 進行選擇時會無法選中WidgetSpan 里的文本」。





PS:其實拖動可以選中,只是這里暫時以不能選中的情況下作為切入點。


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

那么對于最外層的 Text,其實它的文本內容是 "Flutter is the best!",注意這段文本,其實文本里此時是多了兩個空格。
之所以會有這兩個空格,其實是因為WidgetSpan 使用了 0xFFFC 的占位符,這段占位符在渲染時,就會被替換為WidgetSpan 對應的 Hello World 和貓頭圖片。

「那么這時候如果我們選擇復制,復制出來的內容會是 Flutter isthe best!,中間的兩個占位符是不會復制出來,因為在獲取可選擇片段時,會把對應的 placeholderCodeUnit 剔除。

另外,當我們點擊復制的時候,WidgetSpan 所在的Hello World 并沒有被選中,所以此時調用 getSelectedContent 就會得到 null,也就是沒有內容。
所以可以看到: 此時在手動拖拽選擇時,WidgetSpan 里的文本是不會被選中,因為它處于不同的 Text,對于外層 Text 而言它只是個占位符。


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


問題2


如果當我們點擊了全選會怎么樣?如下圖所示,在我們點擊全選之后,可以看到兩個 "奇怪" 的問題:

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

我們首先看第一點,「為什么點擊全選時,WidgetSpan 里的 Hello World 可以被選中」?


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

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

首先我們看,為什么復制出來之后的內容會是Hello World!Flutter isthe best!


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

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

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





此時復制出來的內容會是 Flutter isthe best!Hello World!「因為這個時候會有一個很 "微妙" 的偏差值,導致 Hello World 排序時被排列到最后面」,從而導致 End Handle 不是預期的位置。
另外,這時候您會發現,如下左側動圖所示,「此時拖動 Handle 是可以選中 WidgetSpan 里的 Hello World,其實之前的情況下也可以,不過需要如右側動圖所示,需要從Hello World 開始拖動,「因為最開始的情況下 selectablesHello World 的排序層級更高,所以如果想要拖動選中,也需要從它開始」





目前這個問題在 master 和 stable 分支均可以復現,對應 issue 我也提交在#111021。


最后


雖然SelectionArea 的出現補全了 Flutter 的長久以來的短板之一,不過基于SelectionArea 實現的復雜程度,目前SelectionArea 還有不少的細節需要優化,但是萬事開頭難,本次 3.3 SelectionArea 的落地也算是一個不錯的開始。


最后,相信通過本文大家應該對 SelectionArea 的使用和實現都有了一定的了解。



長按右側二維碼

查看更多開發者精彩分享




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



?點擊屏末||即刻報名參與"開發者說·DTalk"





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

文章出處:【微信公眾號:谷歌開發者】歡迎添加關注!文章轉載請注明出處。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 谷歌
    +關注

    關注

    27

    文章

    6161

    瀏覽量

    105304

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

文章出處:【微信號:Google_Developers,微信公眾號:谷歌開發者】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    云端AI開發者工具怎么

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

    ADS1299EEGFE-PDK如何測量負反饋信號?

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

    請問class D類運放不好用作驅動headphone的原因有哪些?

    請問class D類運放不好用作驅動headphone的原因除了EMI問題,還有沒有其它問題的限制,導致TI沒有生產class D的headphone功
    發表于 11-04 08:06

    鴻蒙Flutter實戰:07混合開發

    。 其優點是主項目開發者可以不關注Flutter實現,不需要安裝配置Flutter開發環境,缺點是無法及時修改Flutter代碼,也不存在
    發表于 10-23 16:00

    安規電容好不好用看這幾點

    安規電容是保護電源和電路的電子元件,需通過安規認證和標準,保證穩定性和可靠性。電氣性能穩定,品牌選擇關鍵。符合標準且品質好的安規電容可確保電子產品正常運行,減少事故風險。
    的頭像 發表于 09-06 16:12 ?359次閱讀
    安規電容<b class='flag-5'>好不好用</b>看這幾點

    安規電容好不好用看這幾點

    安規電容是保護電源和電路的電子元件,需通過安規認證和標準,保證穩定性和可靠性。電氣性能穩定,品牌選擇關鍵。符合標準且品質好的安規電容可確保電子產品正常運行,減少事故風險。
    的頭像 發表于 09-06 16:12 ?254次閱讀

    OPA544芯片的黑色主體材料導熱性好不好?

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

    藍牙信標是什么?藍牙信標好不好用?

    是什么,另外這好不好用呢? 以新銳科創藍牙信標為例 一、藍牙信標是什么? 通過名字我們不難看出,其實藍牙信標的基本用途與藍牙還是有一定關系的,實際上是一個Beacon設備。一般都會被放在室內的一個固定位置,然后可以
    的頭像 發表于 07-09 16:32 ?534次閱讀
    藍牙信標是什么?藍牙信標<b class='flag-5'>好不好用</b>?

    stm32L0串口接收不好用是什么原因導致的?

    stm32L0系列串口在使用中出現,一段時間后串口接收就不好用了,各位能不能給一下使用經驗。
    發表于 07-04 07:42

    STM32F4系列PA1管腳始終3.3V電壓是怎么回事?

    改了,而且估計已經在使用了)。 但是我發現一個奇怪的現象,配置完ADC以后,這個管腳的讀數一開始就是4092這樣的數值。但也不是ADC不好用,因為這個數字是變化的,有時候是4089,有時候是4091
    發表于 06-03 08:24

    超級電容好不好用,試試就知道

    超級電容是一種兼具高功率和高能量特性的新型儲能器件,具有充電快、能量密度高、循環次數多等優點,被廣泛應用于電動汽車、可穿戴設備、工業設備等領域。其性能優越與否需通過實際應用來驗證,選用時應選擇正規廠家生產的超級電容。
    的頭像 發表于 04-11 16:56 ?347次閱讀
    超級電容<b class='flag-5'>好不好用</b>,試試就知道

    超級電容好不好用,試試就知道

    超級電容是一種兼具高功率和高能量特性的新型儲能器件,具有充電快、能量密度高、循環次數多等優點,被廣泛應用于電動汽車、可穿戴設備、工業設備超級電容是一種兼具高功率和高能量特性的新型儲能器件,具有充電快、能量密度高、循環次數多等優點,被廣泛應用于電動汽車、可穿戴設備、工業設備等領域。其性能優越與否需通過實際應用來驗證,選用時應選擇正規廠家生產的超級電容。等領域。其性能優越與否需通過實際應用來驗證,選用時應選擇正規廠家生產的超級電容。
    的頭像 發表于 04-11 16:56 ?431次閱讀
    超級電容<b class='flag-5'>好不好用</b>,試試就知道

    站群服務器好不好 多ip流量大

     站群服務器是一種專門設計用于托管多個網站的服務器,每個網站都綁定一個獨立的IP地址。這種配置方式具有一定的優勢,但也有一些潛在的缺點。那么站群服務器到底好不好呢?Rak部落小編為你整理發布站群服務器好不好。
    的頭像 發表于 04-07 09:57 ?343次閱讀

    插拔類的接線端子,要測試多次吃插拔才算成功

    1、插拔類的端子好不好用
    發表于 03-25 14:28

    開發者】HarmonyOS實踐應用狀態變量共享

    # 開發者 # 【開發者】欄目是為HarmonyOS開發者提供的展示和分享平臺,在這里,大家可以發表自己的技術洞察和見解,也可以展示自己
    的頭像 發表于 12-26 21:20 ?821次閱讀
    【<b class='flag-5'>開發者</b><b class='flag-5'>說</b>】HarmonyOS實踐<b class='flag-5'>之</b>應用狀態變量共享
    主站蜘蛛池模板: chinese野外男女free| 十七岁日本免费完整版BD| 国产最新进精品视频| 调教女M屁股撅虐调教| V8成品人视频| a级男女性高爱潮高清试看| 91av电影在线观看| 2021国产精品一卡2卡三卡4卡| 一二三区乱码不卡手机版| 亚洲日韩成人| 亚洲天码中字| 野草在线视频完整视频| 亚洲色爽视频在线观看| 亚洲综合国产在不卡在线| 野花视频在线观看免费| 一个人免费播放高清在线观看 | 国产亚洲视频精彩在线播放| 国产精品黄色大片| 国产精品伦理一二三区伦理| 国产乱人精品视频AV麻豆| 国产欧美无码亚洲| 狠狠色狠狠色综合系列| 精品一产品大全| 久久亚洲成a人片| 魅男mangay| 日本久久频这里精品99| 偷偷要色偷偷| 亚洲欧美高清在线精品一区| 一色狗影院| 99国产精品久久久久久久日本竹| GAY2022空少被体育生暴菊| 刺激性视频黄页| 国产女人毛片| 久久精选视频| 欧美亚洲国产手机在线有码| 日韩一区二区三区视频在线观看| 午夜天堂一区人妻| 在线成人精品国产区免费| 99久久久A片无码国产精| 高清观看ZSHH96的视频素材 | 竹菊精品久久久久久久99蜜桃|