風景、視角與焦點鏈
查看重點
當使用者開始與 UI 的區域互動時,Fusia 的輸入系統會將其視為意圖的陳述。為了反映這個意圖,Vision 定義了「聚焦」概念,其中之一為檢視畫面,判定為「具有檢視畫面焦點」。一次只能有一個檢視畫面聚焦。
如要查看新聚焦的檢視畫面,顯示「聚焦已聚焦」事件,並針對先前聚焦的檢視畫面通知「檢視畫面遺失」事件。
用戶端可以使用檢視畫面焦點提升互動,例如懸停動畫或遊標閃爍。管理員程式可以使用檢視畫面焦點來協調互動,例如判斷哪些用戶端可以使用 IME,或決定要啟動的捷徑。
轉移檢視畫面焦點
透過程式輔助方式啟動
在某些情況下,建議您透過程式輔助方式轉移檢視畫面焦點。舉例來說,系統 UI 可能想啟動 UI,並將焦點放在擁有搜尋框的檢視畫面上。另一個範例支援 Alt Tab 鍵的瀏覽功能,每次叫用 Alt Tab 鍵時,都會循環切換一組檢視畫面,依序將檢視畫面焦點轉移到每個檢視畫面。
顯然,透過程式輔助方式轉移檢視畫面焦點的能力非常實用。為了限制電源濫用,View 定義了與檢視區塊樹狀結構相連結的檢視畫面焦點轉移政策。一般而言,檢視焦點轉移的範圍限定在要求者檢視畫面的子樹狀結構,因此要求者和要求者與樹狀結構祖係有關。
下方列出政策詳情,但需要聚焦焦點鏈。
由使用者輸入內容啟動
如果將 pointer_auto_focus
設為 true,使用者與 UI 互動時,風景區功能就會從檢視畫面移動為檢視畫面。(智慧螢幕會將該值設為 false,並採用前一節所述的程式輔助焦點變更配置)。
焦點轉移會在以下情況發生:
- 在觸控裝置上,手指觸控開始時,焦點會轉移到輕觸的檢視畫面。
- 在滑鼠裝置上,點選主要按鈕後,焦點就會轉移至已點選的檢視區塊。這項政策遵循「直接操控」的 UI 原則。
即使
pointer_auto_focus
設為 true,風景也不會透過滑鼠懸停觸發聚焦轉移。
聚焦鏈:檢視畫面樹狀結構中的焦點路徑
如果我們只考慮場景圖的檢視畫面部分,則會形成樹狀結構階層,也就是所謂的檢視區塊樹狀結構。父項檢視畫面具有強大的子項檢視畫面,例如重新調整子項檢視畫面的位置、在子項檢視畫面強制執行裁剪範圍,以及隱藏子項的 UI 內容等等。由於檢視區塊階層本身俱有利器,我們將這個檢視畫面當做情境以外的階層為基礎。這個階層會根據聚焦檢視畫面動態變更內容,以「聚焦鏈」表示。
在資料結構中,聚焦鏈只是 ViewRefs 的向量。標準定義為 fuchsia.ui.focus.FocusChain。
不過,這不只是什麼。聚焦鏈會與檢視畫面樹狀結構綁定。它會擷取檢視授權快照 (從根檢視畫面開始,向下通過子系),然後在聚焦的檢視畫面終止。因此依授權數量由多到少排列。聚焦鏈以外的檢視畫面沒有以檢視畫面為基礎的授權。
根據直覺,聚焦鏈是指從檢視區塊樹狀結構根節點到聚焦節點的路徑。
當焦點轉移到其他檢視畫面時,焦點鏈結會隨之變更。YouTube 會管理聚焦鏈結的變更,做為管理檢視區塊樹狀結構和檢視畫面焦點的一環。
由於焦點鏈會嵌入 ViewRefs,並對檢視區塊樹狀結構的階層資訊進行編碼,因此會保留機密資訊。因此,只有信任實體 (例如無障礙管理員) 能夠存取焦點鏈結。
在檢視畫面聚焦事件和聚焦鏈之間競爭
請注意,分派給 UI 用戶端的檢視畫面焦點事件和分派給管理員程式的焦點鏈可能會競爭。這些事件之間沒有全域排序。在操控離散 FIDL 通訊協定的過程中,Fuchsia 元件通常會暴露在分散式系統的複雜性中。
轉移檢視畫面焦點:政策
可以想將檢視畫面焦點轉移為結合三個作業的組合,如下所述。我們談到透過 ViewRefs [v0, v1, ...,
vi, ..., vn]
所討論的焦點鏈 F
,其中檢視畫面焦點目前位於 vn
(終端機元素)。RequestFocus
方法不需要存取焦點鏈結就能正常運作;焦點鏈屬於存放區,而非轉移介面的一部分。
聚焦檢視畫面
祖系檢視畫面可以從子系檢視畫面取得檢視畫面焦點:vi
可叫用 RequestFocus(vi)
,而 View 會遵循要求:vi
會收到檢視焦點事件。此時焦點鏈會變成 [v0, v1, v2, ..., vi]
,其中會捨棄 vi
之後的後續元素。
這項作業會將檢視畫面焦點「向上」提取至呼叫端;請注意,呼叫端仍會位於焦點鏈中。
授予檢視畫面焦點
聚焦的檢視畫面可將檢視畫面焦點授予子系檢視畫面:如果 vm
是 vn
的下階,那麼 vn
可能會叫用 RequestFocus(vm)
,而 View 會遵循以下要求:vm
會收到檢視焦點事件。然後,焦點鏈會變成 [v0, v1, v2, ..., vi, ..., vn, ..., vm]
,其中後續元素會附加至 vn
。
這項作業會將檢視畫面焦點從呼叫端「向下」「向下」推送;請注意,呼叫端將留在焦點鏈中。
版本檢視畫面焦點
焦點鏈中的檢視畫面可將檢視畫面焦點釋出至其直接祖系:如果 vi
的子系在 vn
終止,且 vi
有直接祖系 vh
,則 vi
可能會叫用 RequestFocus()
(無引數),而 View 也會處理要求:vh
會收到檢視焦點事件。此時焦點鏈會變成 [v0, v1, ..., vh]
,其中以 vi
開頭的後續元素會直接捨棄。
這項作業與堆疊彈出類似,因為呼叫端就會從焦點鏈結出來。
雖然「Take 」和「Grant」較為明顯,但「Release」仍需要一些說明。您可能會基於各種原因而需要明確發布的視角焦點,例如:
- 隱藏 UI 元素,不必刪除這些元素
- 關閉強制回應對話方塊,做為返回檢視焦點先前位置的一部分
- 使用者輕觸 UI 中非互動的部分,表示他們希望檢視畫面焦點回到先前的位置
目前,Release 是隱式作業,在生命週期事件 (例如檢視中斷連線或檢視刪除) 期間,ViewModel 會處理此作業。
構圖
只要每項作業都設有先決條件,接管、授權和發布可以任意順序執行。
不適用
我們已考慮以下「超出服務範圍」主題,藉此簡化問題空間:
- 強制回應對話方塊和焦點竊取活動。如果檢視畫面想要建立強制回應對話方塊,而不是在其檢視畫面中建立子檢視畫面或建立 UI 矩形,則應套用至較高授權的層級 (例如系統 UI) 以代表其建立強制回應對話方塊檢視畫面。接著,系統 UI 可將檢視畫面焦點授予該強制回應對話方塊,以及防止使用者觸控將檢視畫面焦點移開的剪刀。進行這項設定後,不在焦點鏈結中的檢視畫面就無法隱密強制回應對話方塊的檢視畫面焦點。
- 安全輸入。系統必須保證從核心傳送至用戶端的「安全輸入」路徑完整性。