<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
在Android螢幕的空間中,大部分的區域我們都是可以隨意繪製,只有一部分割區域是顯示的固定內容:
其中標題列是可選的,除了Material風格的應用應用的並不多,頁面內容就是android.R.id.content
是Activity的主要內容。
而我們主要需要討論的就是 狀態列和導航欄,因為這兩個區域在不同裝置型別,不同的Android版本和不同的廠商下大小和效果是不同的,等等。這些差異無疑增加了我們做頁面適配的複雜程度,也更容易出現相容問題。
在2017年下半年iPhone X的釋出,引入了劉海屏裝置,導致了藍綠大廠爭相效仿,同時又自成一派,頗有一番百家爭鳴之象。 這也導致了一個新的問題 劉海區域適配 ,那時候Android才8.1,並沒有API來支援這螢幕上這多出來的一塊區域,不過好在大部分裝置在客製化時劉海和狀態列高度是一致的。
終於在2018年釋出的Android 9中Google正式支援了劉海屏,客製化了規範約束了裝置廠商,減輕了劉海屏適配的差異問題,但是根源問題並沒有解決。因為劉海區域的存在,可能會出現頁面內容被遮擋,比如:啟用頁廣告跳過按鈕被遮擋的問題,導致被應用商店拒掉的風險。
不過好在Android 9中要求劉海裝置必須有以下行為:
劉海高度預設是和狀態列高度一致依舊沒有變,所以問題又回到了狀態列區域的處理。
所以肯定有同學說了:直接獲取狀態列高度不就可以了適配劉海屏了。像這樣:
val top = context.getStatusBarHeight() titleBar.setPadding(0, top, 0, 0)
這麼說也沒有錯,大部分情況下是沒有問題的。但是既然官方已經適配劉海屏了,也為我們提供了新的API為什麼不用呢:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { window.decorView.post { val top = window.decorView.rootWindowInsets?.displayCutout?.safeInsetTop ?: 0 // val bottom = window.decorView.rootWindowInsets?.displayCutout?.safeInsetBottom ?: 0 titleBar.setPadding(0, top, 0, 0) } }
上面的方案實際上可以獲取上下左右四個方向的安全距離,但大部分情況我們只需要處理頂部就可以了。實際上這已經可以解決我們的問題了,但是還有更好的解決方案方案:
新增依賴:
implementation 'androidx.core:core:1.7.0' // 老版本也可以,但是getInsets() API 還沒新增 // implementation 'androidx.core:core:1.3.0'
使用ViewCompat工具:
ViewCompat.setOnApplyWindowInsetsListener(titleBar) { view: View, insets: WindowInsetsCompat -> //val top = insets.systemWindowInsetTop // 高版本已經過時,可以用下面的api替換 val stableInsets = insets.getInsets( WindowInsetsCompat.Type.systemBars() or WindowInsetsCompat.Type.displayCutout()) titleBar.setPadding(0, stableInsets.top, 0, 0) return@setOnApplyWindowInsetsListener insets }
實際上螢幕安全距離,基本上全部圍繞這一個API,Google也推薦我們這麼做,在很多系統控制元件都能看到它的影子,比如:AppBarLayout、DrawerLayout、NavigationBarView
等等都有用到,內部都是來處理系統安全距離的。
上面提到了手機有各種系統欄(狀態列、導航欄),如果一個全螢幕+劉海屏+透明系統欄+螢幕旋轉的頁面處理這些安全距離就更復雜,比如短視訊頁,這裡先給大家列幾條可能出現的問題:
這些所有的問題通過 ViewCompat.setOnApplyWindowInsetsListener()
來優雅處理, 通過 WindowInsetsCompat.getInsets(type)
可以獲取系統的各個欄的大小, 我們也可以同時獲取多個系統欄的高度,各個距離內部會進行累加,返回一個類似Rect的物件,對應螢幕的左上右下需要插入的距離:
val stableInsets = insets.getInsets( WindowInsetsCompat.Type.statusBars() or WindowInsetsCompat.Type.navigationBars() or WindowInsetsCompat.Type.displayCutout())
然後在對不同位置的控制元件新增對應的邊距。除了上面提到的三種型別的安全距離,還有一些其他的型別,有興趣的可以自己瞭解。
ViewCompat.setOnApplyWindowInsetsListener()
能解決大部分安全距離的問題,但是有一點它是處理不了的,就是 螢幕圓角,這些安全距離的計算是不處理螢幕圓角的,所以如果有圓角要處理那我們就要另闢蹊徑了。
好在Android 12中官方新增了對圓角的支援:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { val roundedCorner = insets.toWindowInsets() ?.getRoundedCorner(RoundedCorner.POSITION_TOP_LEFT) roundedCorner?.center }
我用了Pixel4真機發現能獲取到資料,但是模擬器獲取不到。
除了圓角支援,還有對隱私指示器提供了支援:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { val rect = insets.toWindowInsets()?.privacyIndicatorBounds // 頁面控制元件需要避開這個區域,不然可能會被遮擋 }
隱私指示器的範圍,主要是 攝像頭和麥克風 使用中狀態的指示器邊界,如果是錄製直播或者相機的頁面需要處理這個區域。
除了圓角以外,好像沒有找到官方對打孔屏的支援,可能後面會加入對打孔屏的支援吧。
到此這篇關於API處理Android安全距離詳情的文章就介紹到這了,更多相關 Android安全距離內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45