接下來我將爲你們介紹一個新的系統UI的功能:手勢導航。同時想要利用這個機會和你們聊一聊做爲開發者,應該如何去適配全面屏或者說新的全手勢導航的模式。windows
隨着時間的發展,咱們能夠看到手持設備的體積變得愈來愈小,屏幕自己則變得愈來愈大,而後屏幕在設備上的佔有比例也變得愈來愈高。能夠看到到最近年這些手持設備硬件上面的邊框真的是變得愈來愈來越細小。同時,咱們也看到不少硬件廠商在這方面有更多的創新,例如說可摺疊式的手機。安全
這樣一個全面屏的趨勢,主要是因爲用戶對更大屏幕的需求。固然,這也離不開各個設備廠商在硬件方面各類各樣的創新。ide
咱們也看到,這兩年除了在硬件方面以外,不少的廠商在軟件方面去考慮如何使用全手勢的這種操做來給用戶更多的屏幕空間。不一樣的設備廠商提供了不一樣的手勢操做。佈局
那麼對於在座的開發者來講,這雖然是一個好事情,但也可能意味着咱們的工做量變大了:由於咱們在研發過程當中要適配不一樣的手勢,可能要專門爲一些設備的手勢進行設計、研發、測試等等。post
那麼,從安卓系統角度,咱們就想要去幫你們解決這個問題,因此在今年的 Android Q 咱們爲你們推出了新的手勢導航的功能。測試
你可能仍是看到的是以前比較經典的三個按鍵的導航,那麼你只要進入系統設置,裏面有一個 gesture 選項,而後你就能夠開啓如今全新的手勢導航了。 優化
咱們先從最左邊的來說,能夠看到當用戶從屏幕的底端,也就是如今虛擬的導航按鍵這裏往上推的時候,用戶能夠退出當前應用,也就是說這個手勢代替的是咱們以前的home按鍵,即退出當前應用。spa
中間這個手勢代替的是「用戶回到最已經瀏覽過的應用」手勢,操做是從底部往上推,而後停留。設計
最右邊是今年新增長的另一個手勢,也就是返回的手勢。他代替的是以前三個導航按鍵當中「返回」的按鈕。3d
這張動圖沒有徹底包括新的手勢。在 Beta3 中新的手勢是支持同時向左側滑動和向右側滑動這兩個手勢的。能夠看到,這張動圖中咱們只包括了從左側滑動。當用戶在屏幕的邊緣向左側或者是向右側滑動的時候,用戶就能夠回到上一個頁面了。
說到這裏可能你們會有一個疑問,由於在過去安卓系統上經典的三個按鍵的導航模式推出了不少年,大部分的用戶也很習慣於使用這樣的導航模式,那今年推出的新的全手勢的導航,對於安卓微生態來講意味着什麼呢?
我要先解釋、澄清一下:首先三個按鍵的導航模式咱們會繼續沿用的。
幾個方面的緣由,很重要的一點就是不少的用戶已經習慣於這樣的導航模式,特別是針對於有無障礙需求的一些用戶,對他來講三個按鍵導航能夠幫助他去使用設備,因此咱們會繼續沿用三個按鍵的導航。同時,咱們會要求全部的安卓設備都繼續支持三個按鍵的導航,用戶就永遠有一個能夠返回去的備選方案。
在這個基礎上有今年咱們推出的全手勢導航,具體的手勢內容就是主要的那三種手勢,也就是剛剛你們看到動圖。接下來咱們會繼續和各個廠商努力把手勢導航的這幾個操做統一化,以便幫助開發者去處理一個統一的手勢導航。那麼到這裏 Android Q 中新的手勢導航功能自己我就介紹到這裏。
接下來我想要跟你們聊一聊,做爲開發者如何去面對如今全面屏的趨勢,或者說新的手勢導航,給你們幾點建議。
既然咱們有了更大的屏幕,做爲開發者,咱們但願你們去用這樣一個更大的屏幕。當咱們把原來的佈局放在新的全面屏的時候,可能就會遇到一些跟系統UI有衝突的地方。
這個時候,咱們建議你們利用 insets 這個類來調整你的佈局。
若是說你的應用內部有一些功能,或者說有一些手勢剛好是和系統的新手勢重合或者衝突(大部分的狀況下應該不會有這樣的衝突發生,我以後會給你們一個例子),若是有這樣的狀況,你們務必要把這些問題解決一下。
說了這麼久的全面屏,全面屏到底指的是什麼?
導航欄不光包括我給你們展現的新的手勢導航,同時也包括了三個按鈕的經典式的導航,一樣會推薦你們去使用導航欄的區域,以後會給你們介紹可使用這個區域的 API,這個 API 是在舊的安卓版本上一樣兼容的,因此建議你們在適配 Q 的時候也能夠考慮是否在以前的版本上一樣加入這樣的支持。
另外一方面,若是你的應用像這樣:
那麼在 Android Q 當中咱們也建議你們去使用這樣的狀態欄,目的很簡單:給用戶全面屏的感覺,沉浸式的感覺。
一樣,咱們也建議你們在適配 Q 的時候考慮是否在以前的版本上一樣加入這樣的支持。那麼咱們就能夠看到,咱們如今應用所用的屏幕的範圍,從以前的範圍變成了如圖這樣一個全面屏的範圍。
那麼咱們具體應該怎樣來實現?基本上也是三個部分:
你的應用須要告訴系統,你要在全面屏上佈置顯示的應用內容,在全面屏上顯示的時候可能會出現一些問題。
例如說咱們這裏看到應用內容的最下面的部分,若是沒有作任何優化的話,系統的導航欄可能就會蓋住應用的內容。這個時候,做爲開發者就須要對導航欄進行一些優化。 或者是個人應用內部有一些 view 或者是像上圖中的 floatingActionButton (懸浮按鈕)。若是說你原來開發的時候它的位置是寫死的,那麼當你在全面屏佈置的時候,可能就會有一些跟系統 UI 的衝突,而後用戶就沒有辦法去繼續使用你以前的一些功能了。
那麼咱們來看第一部分,在全面屏上顯示。
我把這些參數大部分列在了這裏,這不是全部的參數。
舉幾個例子:最上面 SYSTEM_UL_FLAG_LOW_PROGFILE,就是要讓系統的 UI 呈現於一個 low profile 的狀態,也就是一個低調的狀態,不要影響到個人應用內容,那麼接下來,若是我傳入的是 SYSTEM_UL_FLAG_NAVIGATION,其實我就是告訴了系統,我要把導航欄隱藏起來。因此第一個部分是要告訴系統 UI 如何顯示。
中間這部分的參數是特別適用於一個視頻或者是遊戲的界面想要給用戶一種沉浸式的體驗,那麼就能夠傳入 SYSTEM_UL_FLAG_IMMERSIVE 這兩個的參數,當用戶須要看到這個系統 UI 按鈕的時候,經過點擊屏幕等等能夠再讓這個系統 UI 出現。
今天我要說的實際上是最下面的這三個參數,經過使用這三個參數你就可讓你的應用在全面屏上顯示。咱們具體來看一下這三個參數:
那麼,針對於狀態欄,若是你須要使用的話,你就要傳入這樣一個參數:STSTEM_UL_FLAG_LAYOUT_FULLSCREEN,這個時候就是告訴了系統,我要在全屏顯示包括狀態欄。
這個參數屬性是咱們在 loli pop 以後就已經推出的,而且建議你們在適配或者是針對於 Android 9.0或9.0之前的設備都應用把導航欄設置爲透明的這樣的一行代碼。
爲何說是 Android9.0或者是9.0之前?由於在 Q 上咱們推薦你們去利用全面屏,因此係統也要想要幫助你們少作一些事情,因此當你在 Android Q 上使用全面屏的時候,系統的導航欄會幫助你自動從新給導航欄着色,並且是動態變化的。稍微想要提一下的是,對於大部分的設備咱們都有這樣一個優化,可是對於某一些機型可能沒有辦法作到這樣子的優化,對於那種狀況,咱們會給他一個 static 的一個顏色。可是在 Android Q 以前咱們就沒有辦法幫你們,因此建議你們在 Android Q 以前,當你要使用導航欄的時候,你須要寫這樣一個代碼,告訴系統說我要把導航欄設置爲 transparent 透明色。
按照剛纔的這兩個例子,我先是把個人應用在全屏上顯示,同時把導航欄設置爲透明,而後就獲得了這樣的結果,但顯然這不是咱們想要的,應用內部的導航和系統的導航徹底重合了,並且應用內部的導航是我要點擊的操做,和系統的點擊操做是徹底衝突的。這個時候,若是有些處理過全屏幕或者是在全屏幕展示本身應用的朋友,可能用過 WindowInsets。
Insets 自己指的是添入物或者是加入的一個範圍。那麼在咱們如今這個情境下,你們能夠把它理解成是系統告訴你個人 UI 所在的位置區域,或者說是個人系統手勢即將出現的位置。你能夠經過這個值來移動應用內部的 view。讓個人 view 和系統的 UI 不產生任何的衝突。
先來看第一類:WindowInsets 類,這個是咱們從 API20 就已經推出的。能夠看到在下面這張圖當中,導航欄式系統的 UI 部分,也就是綠色的那個部分,當應用去全屏寫的時候,FloatingActionButton 被導航欄遮住了,那麼這個時候我須要獲取系統 UI 的位置,我能夠用 getsystemwindowsinsets 這個值來移動個人按鈕,從而避免任何和系統意外的衝突。
剛纔有提到,在 Android Q上有新的手勢導航。既然有了新的手勢導航,也有了新的系統手勢所在的區域。
能夠看到下面的手勢區域是比以前的導航欄的區域要寬的,由於用戶在想要退出的時候,他可能須要操做的空間更大。
在 Android Q 上面咱們也爲你們提供了這樣一個 API:getsystemGestureinsets,來幫助你們去得到如今新的手勢導航所在的 insets 位置。
以前舉的那個例子,FloatingActionButton 的問題,若是說你的應用和手勢導航有一些衝突的,應該如何去解決呢?這裏給你們分享一個例子,若是說應用是對圖片處理的,例如說我看到這張圖片我須要對它進行裁剪,那麼任何一個用戶看到這個界面,它天然會要採起的一個動做,就是從這四個紅點當中去拖拽這張圖片,從而進行裁剪。
一個很差的消息就是在 Android Q 上面,當用戶去作這件事的時候,若是你沒有進行適配,那麼當他去拖拽,系統手勢會有優先級。由於系統不知道你要用這些位置,那麼怎麼辦?顯然,當用戶看到這個界面,他是會去處理這張圖片的,因而咱們就給你們帶來這樣一個 API:setsystemGestureExclutionRects 傳入的參數是一個 list,就是一系列的。rectangle 就是長方形,也就是咱們這裏看到的那四個紅色的點,由於在用戶去拖拽那些區域的時候,用戶是想要進行應用內部的手勢操做,而不是開啓系統自己的手勢操做。爲何只有紅色的區域須要去覆蓋?答案是確定的,由於若是拖拽出那個區域以後,系統手勢導航只是在最邊臨界的位置,那麼你用 API 的時候來得到系統的手勢在哪裏,針對性的把那個區域加入這樣一個被覆蓋的列表當中。這個方法是支持於你們使用返回手勢的,這裏有寫退出應用的手勢除外,由於在新的全手勢導航下,用戶離開應用,惟一的途徑就是從最下面的退出手勢,若是把這個手勢覆蓋了,用戶就永遠沒法離開應用了。因此最下面的區域是強制不能被去除的。
我在這裏稍微停頓一下,由於以前聽到有人說了這樣一個方法:是否是說個人適配工做變得很容易,只要我應用內部的一些區域,我認爲用戶已經習慣這樣用了,因此我去把全部的系統新的手勢都覆蓋掉。
咱們的建議是儘可能不要這樣作,除非在有必要的狀況下。由於很簡單,若是你們有使用過新的手勢操做,你會快注意到,其實返回這個動做是用戶一天當中使用最多的一個動做,因此用戶會很是快的習慣於新的手勢操做,那麼當它進入你的應用,忽然間他習慣的操做的動做被打斷了,這確定不是一個很好的體驗,咱們仍是最大程度 上想給用戶一個很是一致的體驗。
那麼什麼狀況下你要用這個方法呢?就是我剛纔舉的那個例子,由於你們去修改圖片這個例子,很明顯的,任何用戶當他處理這張圖片的時候,他不會看到那些那四個位置,他不會想到要退出,而是很明顯從 UI 上你給了用戶一些提示:你如今要作的是我應用內部的一個操做,而不是說我開啓系統的手勢。因此但願你們在作這些決定的時候,也思考一下用戶會從哪一個方向來看待。
以前說到了有強制的手勢區域,這邊就給你們提供了這樣一個 API 來得到被強制的手勢範圍,你能夠調用 getMandatoryGestureInsets 方法來得到系統上哪一些區域是被系統強制的,也就是說你沒有辦法去覆蓋它,給你本身應用有更高的一個優先級,在 Android Q 當中被強制的手勢就是在最下面的退出應用區域。
稍微總結一下,getsystemwindowinsets 是咱們已經有了一段時間的 API,這個 API 返回的是如今系統的 UI 所在的位置,或者是說未來會出現的位置。當你在用有某些模式可能如今系統 UI 消失了,但用戶可能會從新喚醒它。那麼,經過使用 getsystemwindowinsets 你就能夠得到系統 UI 的位置。
何時使用它呢?
以前看到不少的朋友已經開始 Android Q 了,你可能會發現新的手勢導航針對於 DrawLayout 抽屜式中導航欄沒有很好的在一塊兒合做。咱們也注意到了這個問題,因此在最新的1.10的版本當中,咱們對 DrawLayout 進行了優化,優化以後的 DrawLayout 的呈現形式是當用戶第一次左滑的時候,你的抽屜欄會打開,而後用戶再進行一次左滑,會退出當前應用。
另一個常見的情境,若是你在使用 Carousels,應用內部有這種輪轉式的顯示的話,(一開始咱們聽到不少的開發者都在考慮,由於用戶要拖拽,我要把整個區域邊上的區域所有都覆蓋掉,但其實咱們推出以後,在內部作了一些研究,一些數據也顯示,其實很快用戶就習慣於這樣一個手勢操做,他明白他若是從最邊界去拖拽的話,它是要返回的。其實用戶對於新的的手勢導航並無認爲有很大的衝突。)咱們的建議就是若是你要用 Carousels ,不建議你們去覆蓋那幾個位置的手勢導航,而是讓用戶去習慣於使用這樣一個新的手勢操做。
今天介紹了不少關於全面屏和手勢操做的建議,我在這裏稍微總結一下:
二、有了全面屏就建議你們利用全面屏給用戶帶來一個更好的體驗。緊接着爲了幫助、確保像我剛纔說的抽屜式導航等等這樣的情境有很好的支持,咱們會繼續在Jetpack和MDC當中爲你們加入新的更新和支持,歡迎你們去使用它們。
三、若是你要去覆蓋手勢區域的話,請確保是在有必要的狀況下你纔去覆蓋。