Android屏幕適配(二)

創(chuàng)建可拉伸的九宮格位圖

如果您在改變尺寸的視圖中將位圖用作背景士八,您會(huì)注意到,當(dāng)視圖根據(jù)屏幕尺寸或視圖中的內(nèi)容增大或縮小時(shí)梁呈,Android 會(huì)縮放您的圖片。這通常會(huì)導(dǎo)致明顯的模糊或其他縮放失真官卡。解決方案是使用九宮格位圖哮翘,這種特殊格式的 PNG 文件會(huì)指示哪些區(qū)域可以拉伸饭寺,哪些區(qū)域不可以拉伸艰匙。

九宮格位圖基本上是一種標(biāo)準(zhǔn)的 PNG 文件员凝,但帶有額外的 1 像素邊框健霹,指示應(yīng)拉伸哪些像素(并且?guī)в?.9.png 擴(kuò)展名骤公,而不只是 .png )。如圖 5 中所示凌节,左邊緣和上邊緣的黑線之間的交點(diǎn)是可以拉伸的位圖區(qū)域±萜澹或者叼架,您也可以定義內(nèi)容在視圖內(nèi)應(yīng)進(jìn)入的安全區(qū)域扮饶,方法是以同樣的方式在右邊緣和下邊緣添加線條甜无。


九宮格圖片

將九宮格作為背景應(yīng)用于視圖時(shí)岂丘,框架會(huì)正確拉伸圖片以適應(yīng)按鈕的尺寸奥帘。

針對(duì)所有屏幕尺寸進(jìn)行測(cè)試

務(wù)必針對(duì)各種屏幕尺寸測(cè)試您的應(yīng)用,以便確保界面正確縮放返咱。如果您無法訪問具有各種不同屏幕尺寸的物理設(shè)備评姨,則可以使用 Android 模擬器模擬任何屏幕尺寸吐句。

如果您希望在物理設(shè)備上進(jìn)行測(cè)試嗦枢,但又不想購(gòu)買設(shè)備文虏,則可以使用 Firebase 測(cè)試實(shí)驗(yàn)室訪問 Google數(shù)據(jù)中心內(nèi)的設(shè)備年鸳。

聲明特定的屏幕尺寸支持

如果您不想讓您的應(yīng)用以特定的屏幕尺寸運(yùn)行搔确,您可以設(shè)置屏幕尺寸限制膳算,甚至可以根據(jù)設(shè)備的屏幕配置限制哪些設(shè)備可以安裝您的應(yīng)用畦幢。

支持劉海屏

劉海屏

劉海屏是指某些設(shè)備顯示屏上的一個(gè)區(qū)域延伸到顯示面,這樣既能為用戶提供全面屏體驗(yàn)刊头,又能為設(shè)備正面的重要傳感器留出空間原杂。Android 在搭載 Android 9(API 級(jí)別 28)及更高版本的設(shè)備上正式支持劉海屏。請(qǐng)注意咸产,設(shè)備制造商也可以選擇在搭載 Android 8.1 或更低版本的設(shè)備上支持劉海屏脑溢。

本主題介紹如何實(shí)現(xiàn)對(duì)帶劉海屏的設(shè)備的支持屑彻,包括如何處理“劉海區(qū)域”社牲,即顯示面上包含劉海的無邊框矩形搏恤。

在帶劉海屏的設(shè)備上有什么要求

為了確保一致性和應(yīng)用兼容性陨界,搭載 Android 9 的設(shè)備必須確保以下劉海行為:

  • 一條邊緣最多只能包含一個(gè)劉海菌瘪。
  • 一臺(tái)設(shè)備不能有兩個(gè)以上的劉海俏扩。
  • 設(shè)備的兩條較長(zhǎng)邊緣上不能有劉海录淡。
  • 在未設(shè)置特殊標(biāo)志的豎屏模式下嫉戚,狀態(tài)欄的高度必須至少與劉海的高度持平彬檀。
  • 默認(rèn)情況下窍帝,在全屏模式或橫屏模式下坤学,整個(gè)劉海區(qū)域必須顯示黑邊。

選擇您的應(yīng)用如何處理劉海區(qū)域

如果不希望您的內(nèi)容與劉海區(qū)域重疊略号,請(qǐng)確保您的內(nèi)容不與狀態(tài)欄和導(dǎo)航欄重疊突梦,這樣做一般就足夠了宫患。如果您要將內(nèi)容呈現(xiàn)到劉海區(qū)域中娃闲,則可以使用 WindowInsets.getDisplayCutout() 來檢索DisplayCutout 對(duì)象,該對(duì)象包含每個(gè)劉海區(qū)域的安全邊襯區(qū)和邊界框属拾。您可以使用這些 API 來檢查您的內(nèi)容是否與劉海區(qū)域重疊渐白,以便根據(jù)需要重新放置纯衍。
注意:要在多個(gè) API 級(jí)別管理劉海實(shí)現(xiàn),您還可以使用 AndroidX 庫(kù)(可通過 SDK 管理器獲得)DisplayCutoutCompat歌亲。
Android 還允許您控制是否在劉海區(qū)域內(nèi)顯示內(nèi)容。窗口布局屬性 layoutInDisplayCutoutMode 控制您的內(nèi)容如何呈現(xiàn)在劉海區(qū)域中泉唁。您可以將 layoutInDisplayCutoutMode 設(shè)為以下某個(gè)值:

  • LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT 這是默認(rèn)行為,如上所述拴鸵。在豎屏模式下劲藐,內(nèi)容會(huì)呈現(xiàn)到劉海區(qū)域中兄渺;但在橫屏模式下挂谍,內(nèi)容會(huì)顯示黑邊。
  • LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES 在豎屏模式和橫屏模式下妄田,內(nèi)容都會(huì)呈現(xiàn)到劉海區(qū)域中形庭。
  • LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER 內(nèi)容從不呈現(xiàn)到劉海區(qū)域中萨醒。

您可以通過編程或在 Activity 中設(shè)置樣式來設(shè)置劉海模式。以下示例定義了一種樣式旨椒,您可以使用它將LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES 屬性應(yīng)用到 Activity综慎。

<style name="ActivityTheme"> 
   <item name="android:windowLayoutInDisplayCutoutMode"> shortEdges <!-- default, shortEdges, never --> </item>
</style>

下面幾部分更詳細(xì)地介紹了不同的劉海模式好港。

默認(rèn)行為

默認(rèn)情況下,在未設(shè)置特殊標(biāo)志的豎屏模式下拔莱,在帶劉海屏的設(shè)備上塘秦,狀態(tài)欄的大小會(huì)調(diào)整為至少與劉海一樣高嗤形,而您的內(nèi)容會(huì)顯示在下方區(qū)域。在橫屏模式或全屏模式下,您的應(yīng)用窗口會(huì)顯示黑邊叶组,因此您的任何內(nèi)容都不會(huì)顯示在劉海區(qū)域中。

將內(nèi)容呈現(xiàn)在短邊劉海區(qū)域中

對(duì)于某些內(nèi)容(如視頻历造、照片侣监、地圖和游戲),呈現(xiàn)在劉海區(qū)域中是一種很好的方法姓蜂,這樣能夠?yàn)橛脩籼峁┏两懈鼜?qiáng)的全面屏體驗(yàn)医吊。如果設(shè)置了 LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES束莫,則在豎屏模式和橫屏模式下览绿,內(nèi)容都會(huì)延伸到顯示屏的短邊上的劉海區(qū)域享钞,而不管系統(tǒng)欄處于隱藏還是可見狀態(tài)。請(qǐng)注意暑脆,窗口無法延伸到屏幕的長(zhǎng)邊上的劉海區(qū)域沥曹。使用此模式時(shí),請(qǐng)確保沒有重要內(nèi)容與劉海區(qū)域重疊壶栋。
請(qǐng)注意:Android 可能不允許內(nèi)容視圖與系統(tǒng)欄重疊。要替換此行為并強(qiáng)制內(nèi)容延伸到劉海區(qū)域毙玻,請(qǐng)通過 View.setSystemUiVisibility(int) 方法將以下任一標(biāo)志應(yīng)用于視圖可見性:

  • SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
  • SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
  • SYSTEM_UI_FLAG_LAYOUT_STABLE

下面是一些 LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES 示例:


示例圖1

示例圖2

請(qǐng)注意施符,邊角處的劉海可等同于在短邊上听哭,因此適用同樣的行為:


示例圖3

從不將內(nèi)容呈現(xiàn)在劉海區(qū)域中

如果設(shè)置了 LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER,則不允許窗口與劉海區(qū)域重疊败明。此模式應(yīng)該用于暫時(shí)設(shè)置 View.SYSTEM_UI_FLAG_FULLSCREEN 或View.SYSTEM_UI_FLAG_HIDE_NAVIGATION 的窗口,以避免在設(shè)置或清除了該標(biāo)志時(shí)執(zhí)行另一種窗口布局蜒车。
請(qǐng)查看下面的 LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER 示例:


示例圖4

示例圖5

特殊模式

某些搭載 Android 8.1(API 級(jí)別 27)或更低版本的設(shè)備支持一種特殊模式嬉挡,可讓用戶將顯示黑邊的全屏或橫屏應(yīng)用延伸到劉海區(qū)域。此模式通常使用導(dǎo)航欄中的切換開關(guān)來控制焊夸,在延伸屏幕之前會(huì)顯示一個(gè)對(duì)話框,要求用戶進(jìn)行確認(rèn)揪阶。


示例圖6

支持劉海屏的最佳做法

使用劉海屏?xí)r冰沙,請(qǐng)務(wù)必考慮以下幾點(diǎn):

  • 不要讓劉海區(qū)域遮蓋任何重要的文本、控件或其他信息侥啤。
  • 不要將任何需要精細(xì)輕觸識(shí)別的交互式元素放置或延伸到劉海區(qū)域。劉海區(qū)域中的輕觸靈敏度可能要比其他區(qū)域低一些赁炎。
  • 避免對(duì)狀態(tài)欄高度進(jìn)行硬編碼琅攘,因?yàn)檫@樣做可能會(huì)導(dǎo)致內(nèi)容重疊或被切斷逗抑。如有可能,請(qǐng)使用WindowInsetsCompat 檢索狀態(tài)欄高度寒亥,并確定要對(duì)您的內(nèi)容應(yīng)用的適當(dāng)內(nèi)邊距褂傀。


    示例圖7
  • 不要假定應(yīng)用會(huì)占據(jù)整個(gè)窗口鳄梅,而應(yīng)使用 View.getLocationInWindow() 來確認(rèn)應(yīng)用的位置叠国。不要使用View.getLocationOnScreen()。
  • 務(wù)必妥善處理進(jìn)入或退出全屏模式戴尸。
  • 對(duì)于豎屏模式下的默認(rèn)劉海行為,如果劉海區(qū)域位于頂部邊緣,并且窗口未設(shè)置FLAG_FULLSCREEN 或View.SYSTEM_UI_FLAG_FULLSCREEN,則窗口可以延伸到劉海區(qū)域翅阵。同樣,如果劉海區(qū)域位于底部邊緣,并且窗口未設(shè)置 View.SYSTEM_UI_FLAG_HIDE_NAVIGATION,則窗口可以延伸到劉海區(qū)域短条。在全屏模式或橫屏模式下赋访,窗口的布局方式應(yīng)確保其不與劉海區(qū)域重疊可都。
  • 如果您的應(yīng)用需要進(jìn)入和退出全屏模式蚓耽,請(qǐng)使用 shortEdges 或 never 劉海模式答姥。默認(rèn)劉海行為可導(dǎo)致應(yīng)用中的內(nèi)容在全屏模式轉(zhuǎn)換過程中上下移動(dòng)序宦,如下圖所示:


    示例圖8
  • 在全屏模式下,在使用窗口坐標(biāo)與屏幕坐標(biāo)時(shí)應(yīng)保持謹(jǐn)慎遂填,因?yàn)樵陲@示黑邊的情況下,您的應(yīng)用不會(huì)占據(jù)整個(gè)屏幕灯荧。由于顯示黑邊礁击,因此根據(jù)屏幕原點(diǎn)得到的坐標(biāo)與根據(jù)窗口原點(diǎn)得到的坐標(biāo)不再相同。您可以根據(jù)需要使用 getLocationOnScreen() 將屏幕坐標(biāo)轉(zhuǎn)換為視圖坐標(biāo)码荔。下圖展示了內(nèi)容顯示黑邊時(shí)這兩種坐標(biāo)有何不同:


    示例圖9

    處理 MotionEvent 時(shí),請(qǐng)使用 MotionEvent.getX() 和 MotionEvent.getY() 來避免類似的坐標(biāo)問題巨双。不要使用MotionEvent.getRawX() 或 MotionEvent.getRawY()。

測(cè)試您的內(nèi)容如何呈現(xiàn)

示例圖10

請(qǐng)務(wù)必測(cè)試應(yīng)用的所有屏幕和體驗(yàn)。如有可能麻献,在具有不同類型劉海屏的設(shè)備上進(jìn)行測(cè)試猜扮。如果您沒有帶劉海屏的設(shè)備勉吻,可以在搭載 Android 9 的任意設(shè)備或模擬器上模擬一些常見的劉海配置,具體操作步驟如下:

  1. 啟用開發(fā)者選項(xiàng)旅赢。
  2. 在開發(fā)者選項(xiàng)屏幕中齿桃,向下滾動(dòng)到繪制部分,然后選擇模擬劉海屏煮盼。
  3. 選擇劉海類型短纵。

布局選擇

  • 線性布局(Linearlayout)
  • 相對(duì)布局(RelativeLayout推薦)
  • 幀布局(FrameLayout)
  • 絕對(duì)布局(AbsoluteLayout禁用)
  • 約束布局 (Constraintlayout推薦)

使用自適應(yīng)尺寸

  • wrap_content,match_parent,weight, dp, 0dp
  • 不要使用px

今日頭條適配方案

px值 = dp值 * metrics.density ,這里的 density 是指的手機(jī)的屏幕密度僵控,由系統(tǒng)提供香到,不同的手機(jī)的 density 可能不同;所以我們不能直接使用系統(tǒng)的 density 报破,需要篡改 density 來達(dá)到適配的目的

百分比適配

  1. 以某一分辨率為基準(zhǔn)悠就,生成所有分辨率對(duì)應(yīng)像素?cái)?shù)列表
  2. 將生成像素?cái)?shù)列表存放在res目錄下對(duì)應(yīng)的values文件下
  3. 根據(jù)UI設(shè)計(jì)師給出設(shè)計(jì)圖上的尺寸,找到對(duì)應(yīng)像素?cái)?shù)的單位充易,然后設(shè)置給控件即可

多使用約束布局ConstraintLayout

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
禁止轉(zhuǎn)載梗脾,如需轉(zhuǎn)載請(qǐng)通過簡(jiǎn)信或評(píng)論聯(lián)系作者。
  • 序言:七十年代末盹靴,一起剝皮案震驚了整個(gè)濱河市炸茧,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌稿静,老刑警劉巖宇立,帶你破解...
    沈念sama閱讀 218,941評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異自赔,居然都是意外死亡妈嘹,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門绍妨,熙熙樓的掌柜王于貴愁眉苦臉地迎上來润脸,“玉大人,你說我怎么就攤上這事他去”醒保” “怎么了?”我有些...
    開封第一講書人閱讀 165,345評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵灾测,是天一觀的道長(zhǎng)爆价。 經(jīng)常有香客問我,道長(zhǎng),這世上最難降的妖魔是什么铭段? 我笑而不...
    開封第一講書人閱讀 58,851評(píng)論 1 295
  • 正文 為了忘掉前任骤宣,我火速辦了婚禮,結(jié)果婚禮上序愚,老公的妹妹穿的比我還像新娘憔披。我一直安慰自己,他們只是感情好爸吮,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評(píng)論 6 392
  • 文/花漫 我一把揭開白布芬膝。 她就那樣靜靜地躺著,像睡著了一般形娇。 火紅的嫁衣襯著肌膚如雪锰霜。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,688評(píng)論 1 305
  • 那天桐早,我揣著相機(jī)與錄音癣缅,去河邊找鬼。 笑死勘畔,一個(gè)胖子當(dāng)著我的面吹牛所灸,可吹牛的內(nèi)容都是我干的丽惶。 我是一名探鬼主播炫七,決...
    沈念sama閱讀 40,414評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼钾唬!你這毒婦竟也來了万哪?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,319評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤抡秆,失蹤者是張志新(化名)和其女友劉穎奕巍,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體儒士,經(jīng)...
    沈念sama閱讀 45,775評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡的止,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了着撩。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片诅福。...
    茶點(diǎn)故事閱讀 40,096評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖拖叙,靈堂內(nèi)的尸體忽然破棺而出氓润,到底是詐尸還是另有隱情,我是刑警寧澤薯鳍,帶...
    沈念sama閱讀 35,789評(píng)論 5 346
  • 正文 年R本政府宣布咖气,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏崩溪。R本人自食惡果不足惜浅役,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望悯舟。 院中可真熱鬧担租,春花似錦、人聲如沸抵怎。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)反惕。三九已至尝艘,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間姿染,已是汗流浹背背亥。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評(píng)論 1 271
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留悬赏,地道東北人狡汉。 一個(gè)月前我還...
    沈念sama閱讀 48,308評(píng)論 3 372
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像闽颇,于是被迫代替她去往敵國(guó)和親盾戴。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容