① android中相同解析度不同尺寸的手機怎麼適配
Android應用如何適配不同解析度的手機
主要分三塊考慮
1 )界面配置
根據不同的解析度,創建手機界面文件
例子:
在res下創建 layout-800x480
layout-480x320
並在各自不同解析度的文件夾下創建界面文件
2)圖片配置
不同的解析度,界面的長寬比不一致,需要不同規格的圖片
在drawable-hdpi,drawable-ldpi,drawable-mdpi 中放不同解析度的圖片
注:為了減小整個應用程序安裝包大小,選用最高解析度適配,特殊界面圖片特殊處理
3)動態實現的界面,樣式的設定
不同解析度,界面的字體大小,字體等需要不同的樣式,且需要動態生成的情況下,
需要把不同解析度的配置信息保存到應用中。
例子:
在RES里創建 values-480x320 values-800x400 value-1280x720
並在創建的文件夾中分別創建dimens.xml
<dimen name="Text_size">30px</dimen>
在程序中直接調用R.dimen.Text_size
int sizeOfText = (int) this.getResources().getDimension(R.dimen.Text_size);
注:實際應用發現,字體大小適配時
比如只適配了如下屏幕字體
values-480x320 values-800x480 value-1280x720
當出現手機屏幕解析度為 854x480時會自動找最大字體適配 (value-1280x720)
總結:如果字體800x480以上沒有適配,手機自動按最大解析度適配.
② Android-屏幕適配全攻略(絕對詳細)(一)
關鍵字: 屏幕適配 px dp dpi sp large限定符 .9.png
前言: 這篇文章依然是我在 [慕課網 ][h]學習 凱子哥 的同名視頻 Android-屏幕適配全攻略 ,所記錄下來的筆記---凱子哥講得真的超詳細。
[h]: http://www.imooc.com/ "MOOC"
從上圖可以看出,主流的解析度是前六種:1280×720、1920×1080、800×480、854×480、960×540、1184×720,不過我們有解決方案。看完這篇文章,想必你就可以解決常見的屏幕適配問題。
接下來正式進入正題。
介紹幾個在Android屏幕適配上非常重要的名詞:
屏幕尺寸 是指屏幕對角線的長度。單位是英寸,1英寸=2.54厘米
屏幕解析度 是指在橫縱向上的像素點數,單位是px,1px=1像素點,一般是縱向像素橫向像素,如1280×720
屏幕像素密度 是指每英寸上的像素點數,單位是dpi,即「dot per inch」的縮寫,像素密度和屏幕尺寸和屏幕解析度有關
dip: Density Independent Pixels(密度無關像素)的縮寫。以 160dpi 為基準,1dp=1px
dp: 同 dip
dpi: 屏幕像素密度的單位,「dot per inch」的縮寫
px: 像素,物理上的絕對單位
sp: Scale-Independent Pixels的縮寫,可以根據文字大小首選項自動進行縮放。Google推薦我們使用12sp以上的大小,通常可以使用12sp,14sp,18sp,22sp,最好不要使用奇數和小數。
用於區分不同的像素密度。
在Google官方開發文檔中,說明了 ** mdpi:hdpi:xhdpi:xxhdpi:xxxhdpi=2:3:4:6:8 ** 的尺寸比例進行縮放。例如,一個圖標的大小為48×48dp,表示在mdpi上,實際大小為48×48px,在hdpi像素密度上,實際尺寸為mdpi上的1.5倍,即72×72px,以此類推。
我們可以通過以下幾種方式來支持各種屏幕尺寸:
wrap_content: 根據控制項的內容設置控制項的尺寸
math_parent: 根據父控制項的尺寸大小設置控制項的尺寸
weight: 權重,在線性布局中可以使用weight屬性設置控制項所佔的比例
例如,我們要實現下圖所顯示的效果:當屏幕尺寸改變時,new reader控制項兩邊的控制項大小不變,new reader控制項會占完剩餘的空間。
具體布局文件如下:
小插曲: 關於 android:layout_weight 屬性
一般情況,我們都是設置要進行比例分配的方向的寬度為0dp,然後再用權重進行分配。如下:
效果為:
效果為:
button1寬度=L+(L-2L)×1/3=2/3L
button2寬度=L+(L-2L)×2/3=1/3L
當然,還有其他的方式,都可以運用此公式進行計算。
在實際開發中,我們一般使用0dp的方式,而不使用其他方式。
簡單的布局一般都使用 線性布局 ,而略微復雜點的布局,我們使用 相對布局 ,大多數時候,我們都是使用這兩種布局的嵌套。
我們使用 相對布局 的原因是, 相對布局 能在各種尺寸的屏幕上保持控制項間的相對位置。
res/layout/main.xml 單面板:
res/layout-large/main.xml 雙面板:
如果這個程序運行在屏幕尺寸大於7inch的設備上,系統就會載入 res/layout-large/main.xml 而不是 res/layout/main.xml ,在小於7inch的設備上就會載入 res/layout/main.xml 。
需要注意的是,這種通過 large 限定符分辨屏幕尺寸的方法,適用於android3.2之前。在android3.2之後,為了更精確地分辨屏幕尺寸大小,Google推出了最小寬度限定符。
res/layout-sw600dp/main.xml ,雙面板布局: Small Width 最小寬度
這種方式是不區分屏幕方向的。這種最小寬度限定符適用於android3.2之後,所以如果要適配android全部的版本,就要使用 large 限定符和 sw600dp 文件同時存在於項目 res 目錄下。
這就要求我們維護兩個相同功能的文件。為了避免繁瑣操作,我們就要使用布局別名。
由於後兩個文具文件一樣,我們可以用以下兩個文件代替上面三個布局文件:
res/layout/main.xml 單面板布局
res/layout/main_twopanes.xml 雙面板布局
然後在 res 下建立
res/values/layout.xml 、
res/values-large/layout.xml 、
res/values-sw600dp/layout.xml 三個文件。
默認布局
res/values/layout.xml :
Android3.2之前的平板布局
res/values-large/layout.xml :
Android3.2之後的平板布局
res/values-sw600dp/layout.xml :
這樣就有了 main 為別名的布局。
在activity中 setContentView(R.layout.main);
這樣,程序在運行時,就會檢測手機的屏幕大小,如果是平板設備就會載入 res/layout/main_twopanes.xml ,如果是手機設備,就會載入 res/layout/main.xml 。我們就解決了只使用一個布局文件來適配android3.2前後的所有平板設備。
如果我們要求給橫屏、豎屏顯示的布局不一樣。就可以使用 屏幕方向限定符 來實現。
例如,要在平板上實現橫豎屏顯示不用的布局,可以用以下方式實現。
res/values-sw600dp-land/layouts.xml :橫屏
res/values-sw600dp-port/layouts.xml :豎屏
自動拉伸點陣圖,即android下特有的 .9.png 圖片格式。
當我們需要使圖片在拉伸後還能保持一定的顯示效果,比如,不能使圖片中的重要像素拉伸,不能使內容區域受到拉伸的影響,我們就可以使用 .9.png 圖來實現。
要使用 .9.png ,必須先得創建 .9.png 圖片,androidSDK給我們提供了的工具就包含 .9.png 文件的創建和修改工具。雙擊 SDK安裝目錄 oolsdraw9patch.bat ,就會打開下圖所示的窗口。
下面是一個例子:
Button屬性設置:
如果我們選擇的內容區域偏差太大,可能就不會顯示出text值 BUTTON 。
好了,這篇文章寫的有點多了,剩下的內容放在 下篇文章 記錄吧。
內容提要:
解決方案-支持各種屏幕密度
解決方案-實施自適應用戶界面流程
未完待續
③ Android 屏幕適配
Android的屏幕大同小異,解析度也是各種各樣,手機App上的差異性還沒那麼明顯,基本用Dp & weight就可以比較好的適配各種手機。但是在Pad上的表現就不盡如意,而且發現像華為Pad Pro這種高端設備,是可以通過系統設置去設置修改系統的density值,導致整個如果只用一套DpUI布局去實現,會出現很奇怪的UI效果,基本不能適配。這時候就需要對UI進行適配。通過資料查詢,需要了解如下的幾個概念
1.px,pixel 就是像素,最基本的真實顯示單位
2.dp,dip, Density-independent pixel,設備的獨立像素,1dp表示在屏幕像素點密度為160ppi時1px長度
3.ppi, pixel per inch ,每英寸對角像素點,這個是物理上的
4.dpi, dot per inch ,每英寸多少個點,這個是軟體上的,這里的點跟像素點不同
5.sp: scale-independent pixel, 字體大小單位
簡單換算就是
ppi =根號( 橫屏像素點平方+縱屏像素點平方)➗對角線的長度,這個長度是一英寸
1dp = (dpi/160) px
然後有些不同尺寸手機的ppi可能是420, 430, 440, 450, 460.,由於物理ppi上是固定的,改變不了,為了適配,通過人為設置一個dpi,來規范這些差不多ppi值,使得這些相差差不多的屏幕都是通用一個dpi,也就是使用同一套設計方案。
一開始通過dp值來實現適配,是可以解決大部分適配問題,但是在遇到pad這種設備,由於是橫屏,而且系統設置還可以修改density值,使得用一套固定屏幕(比如1280 * 800)的方向變得不是那麼合適。
這時候想到可以通過Android中 dimens中定義dimen值,Android中可以通過sw去搜索對應的dimen值表來獲取對應的配置,smallestWidth適配,sw限定符適配,只要我們把對應的表通過換算,得到一個新值,就可以得到在不同的density值中得到對應的dp值表,解決華為上一個設備對應不同density值的問題。
那麼問題來了,如果去得到sw不同的dimens呢,網上的方法很多,有些自己寫腳本,有些自己寫程序生成,為了就是列舉所有的值,一般1-1000dp,然後基於一個基準,比如360dp寬度,去換算出不同屏幕寬度的dimens值,這里我推薦Android Studio的插件ScreenMatch,先安裝插件
然後在values中創建dimens文件夾,並創建dimens.xml,其中寫上自己定義的dp值,如下
然後在該文件右鍵,選擇screenmatch
插件就會生成一堆其他屏幕的dimens文件,並且自動生成1-800的其他dp值,基本滿足開發中的定義,如果沒有的話,就自行在這里定義,然後重新生成。
關於ScreenMatch的生成還有一個基準,就是基於那個dpi來生成,通過插件生成,在根目錄會多出了兩個文件,一個example, 一個config文件
這里我們看看properties文件,內容如下
其中base_dp=850就是基於850,然後可以通過match_dp去調整要適配的dpi值。
通過這方方式,會在dimens文件自動生成dimen文件
在網上看到,還可以通過修改density去修改,這種方式有空我在試試
④ Android 屏幕解析度適配
Android屏幕解析度千奇百怪,怎麼讓app在不同的解析度的設備上「看起來一樣」呢?
你也許還有以下疑惑:
這篇文章將會針對以上問題一一解答。
Pixels 我們看到屏幕上的圖像由一個個像素組成,像素里包含色彩信息。
如常說的手機解析度:1080 x 1920 指的是手機寬度可展示1080像素,高度可展示1920像素。
Pixels Per Inch 每英寸長度所具有的像素個數,單位面積內像素越多,圖像顯示越清晰。
ppi一般用在顯示器、手機、平板等描述屏幕精細度。
Dots Per Inch 每英寸長度所具有的點數。
dpi一般用來描述列印(書本、雜志、電報)的精細度
density-independent pixels (device-independent pixels 我查了一下,官網更多時候使用前者,有的時候也顯示後者),dip是縮寫,也可以更簡單些稱作dp。該單位的目的是屏蔽不同設備密度差異,後面細說。
Scalable pixels 用於設置字體,在用戶更改字體大小時候會適配。
澄清了基本概念,我們現在從一個例子開始說明以上單位之間的區別與聯系。
布局文件里有個View,長寬都是200px,分別在解析度為480(寬)x800(高)簡稱A設備、1080(寬)x1920(高)簡稱B設備,效果如下:
左邊是A設備,右邊是B設備。問題出來了,同樣長寬都是200px,為啥A設備顯示很大,B設備顯示很小呢?你可能會說B設備的橫向解析度1080比A設備的480大,所以在B設備上看起來比較小。來看看A、B設備橫向到底是多少英寸,怎麼來計算呢?這時候就需要用到ppi了,既然知道橫向的像素點個數,也知道每英寸能容納的像素點,當然可以得知橫向的尺寸了。
其中一種方式獲取DisplayMetrics對象:
A設備寬度尺寸:480(px)/240(ppi)=2inch
B設備寬度尺寸:1080(px)/420(ppi)=2.5inch
可以看出,A、B設備尺寸差別不大。A設備ppi=240 B設備ppi=420,明顯地看出B設備單位長度上比A設備能夠容納更多的像素,因此同樣的200px,B設備只需要較小的尺寸就能夠顯示,因此在B設備上的view看起來比A設備小很多。
知道了問題的原因,然而顯示的效果卻不能接受。
我們總不能自己判斷每個設備的ppi,然後計算實際需要多少像素,再動態設置view的大小吧,那layout里的靜態布局大小就無法動態更改適應了。想當然的能有一個統一的地方替我們轉換,沒錯!Android系統已經幫我們實現了轉換。接下來就是dpi、dp出場了。
Android系統使用dpi來描述屏幕的密度,使用dp來描述密度與像素的關系。
A設備dpi=240
B設備dpi=420
Android系統最終識別的單位是px,怎麼將dpi和px關聯起來呢?,答案是dp。
Android規定當dpi=160時,1dp=1px,當dpi=240時,1dp=1.5px,依此類推,並且給各個范圍的dpi取了簡易的名字加以直觀的識別,如120<dpi<=160,稱作為mdpi,120<dpi<=240 稱作hdpi,最終形成如下規則:
現在知道了dp能夠在不同dpi設備上對應不同px,相當於中間轉換層,我們只需要將view長寬單位設置為合適的dp,就無需關注設備之間密度差異,系統會幫我們完成dp-px轉換。將我們之前的例子稍微更改,再看看效果驗證一下:
通過上面對dp的了解,我們知道在設定view大小、間距時使用dp能最大限度地屏蔽設備密度之間的差異。可能你就會問了,那bitmap展示的時候如何適配不同密度的設備呢?
自定義view從磁碟上載入一張圖片,並將之顯示在view上,view的大小決定於bitmap大小。依舊以上述A、B設備為例,展示結果如下:
左邊是A設備,右邊是B設備。
明顯地看出,在A設備顯示比B設備大很多,實際上和我們之前用px來描述view的大小原理是一樣的,bitmap的寬、高都是px在描述,而bitmap決定了view的寬、高,最終導致A設備和B設備上的view大小(寬、高像素)是一樣的,而它們屏幕密度又不相同,因此產生了差異。
那不會每次都需要我們自己根據屏幕密度來轉換bitmap大小吧?幸運的是,Android已經為我們考慮到了。
生成不同密度的目錄有什麼作用?
A設備dpi=240,根據dpi范圍,屬於hdpi
B設備dpi=420,根據dpi范圍,屬於xxhdpi
圖片原始尺寸:photo1.jpg(寬高 172px-172px)
當我們想要在不同密度設備上顯示同一張圖片並且想要「看起來一樣大時」。假設設計的時候以hdpi為准,放置photo1.jpg為172*172,那麼根據計算規則在xxhdpi上需要設置photo1.jpg為:
現在hdpi和xxhdpi目錄下分別存放了同名圖片:photo1.jpg,只是大小不同。當程序運行的時候:
來看看效果:
左邊A設備,右邊B設備
針對不同的密度設計不同的圖片大小,最大限度保證了同一圖片在不同密度設備上表現「看起來差不多大」。
來看看A、B設備上圖片占內存大小:
說明在B設備上顯示photo1.jpg需要更多的內存。
上邊只是列舉了hdpi、xxhdipi,同理對於mdpi、xhdpi、xxxhdpi根據規則放入相應大小的圖片,程序會根據不同的設備密度從對應的mipmap文件夾下載入資源。如此一來,我們無需關注bitmap在不同密度設備上顯示問題了。
在mipmap各個文件夾下都放置同一套資源的不同尺寸文件似乎有點太佔apk大小,能否只放某個密度下圖片,其餘的靠系統自己適配呢?
現在只保留hdpi下的photo1.jpg圖片,看看在A、B設備上運行情況如何:
看起來和上張圖差不多,說明系統會幫我們適配B設備上的圖片。
再來看看A、B設備上圖片占內存大小:
先看A設備:
對比photo1.jpg 分別放在hdpi、xxhdpi和只放在hdpi下可以看出:B設備上圖片所佔內存變小了。為什麼呢?接下來從源碼里尋找答案。
A、B設備同樣載入hdpi/photo1.jpg,返回的bitmap大小不相同,我們從這方法開始一探究竟。
上面涉及到的關鍵點是density,分別是TypedValue的density和Options的density。
先來看看TypedValue density:
再來看看Options density
現在分析B設備載入hdpi/photo1.jpg如何做的:
和我們之前調試的結果一致。
B設備是怎麼決定使用hdpi下的圖片資源呢?
根據實驗(嘗試找了源碼,沒怎麼看懂,因此只是做了實驗,可能在不同密度設備上找尋規則不一樣):B設備先找屬於自己密度范圍文件夾下的圖片,B設備屬於xxhdpi,先查看xxhdpi有沒有photo1.jpg,如果沒有則往更高的密度找,比它高的密度是xxxhdpi,還是沒有,則往低密度找,找xhdpi,沒有再找hdpi,找到了則返回構造好的TypedValue,剩下的就是我們前面分析的。
既然我們只想放某個密度下的一份切圖,該放哪個密度下呢?從系統尋找規則看,更推薦放置在更高密度下的,因為如果放在低密度下,那麼當運行在高密度設備上時,圖片會進行放大,可能導致不清晰。我一般習慣放在xxhdpi下。
Android Studio默認創建了不同密度的mipmap文件夾,默認放置了ic_launcher.png。我們普通的切圖該放drawable還是mipmap下呢?對於這個問題網上也是眾說紛紜,實際上對於我們來說,關注的重點是圖片放在drawable或者mipmap,載入出來bitmap是否有差異,如果沒有差異放在哪就看習慣了。通過實踐,普通的切圖放drawable和mipmap下載入出來的bitmap是沒有差異的,只不過用drawable的話需要自己創建不同密度的文件夾。我習慣於放在drawable下(啟動圖標logo還是放在mipmap下)。
前邊 [注1] 留了個問題,我們使用dp來表示view的大小了,為啥兩個看起來還是有些差距?下面我們更加直觀地看一個例子。
A設備dpi=240 密度1.5 解析度(寬高px):480 * 800
B設備dpi=420 密度2.625 解析度(寬高px):1080 * 1794
換算成dp
A設備解析度:320dp * 533dp
B設備解析度:411dp * 683dp
依舊是上邊的例子:
將view寬高分別設置為320dp,看看效果:
左邊A設備,右邊B設備
可以看出同樣的320dp大小,A設備鋪滿了屏幕,而B設備沒有。這效果顯然是不能接受的,Android考慮到不同設備寬高不同,推出了"寬高限定符"。以A、B設備為例:
在res文件夾下創建文件夾:
假設設計師出圖是按照800x480,那麼我們創建dimen文件的時候
該文件放在values-800x480文件夾下。
根據解析度比例算出1794x1080的dimen值
這樣子,A、B設備載入資源的時候使用對應解析度限定符下的px,如果找不到再找默認值,可以在一定程度上解決屏幕寬高碎片化適配問題。
但是這樣子的限定比較嚴格,需要測試各種解析度,後來Android又推出了"smallest-width"簡稱最小寬度限制。
A設備寬320dp
B設備寬411dp
假設設計師切圖標准屏幕寬是320dp(A設備),那麼可以定義如下dimen.xml文件
該文件放在values-sw320dp文件夾下
根據規則,計算B設備dimen.xml
現在我們繼續來看之前的view
通過對dimen引用,A設備尋找和自己寬度一樣的dimen文件,找到values-sw320dp,dp320=320dp。B設備尋找和自己寬度一樣的dimen文件,找到values-sw411dp,dp320=410dp。這樣子同樣的dp320,得出不同的值,就適配了屏幕寬度不同的問題。
看看效果:
這次B設備也鋪滿了屏寬。
綜上,為了適配不同屏幕大小,推薦使用dp+smallest-width。
獲取設備dpi最終都是從這方法獲取的,實際上就是讀取系統的配置文件。因此我們也可以通過adb shell 獲取:
可以看出dpi是系統配置好的,當然有些手機是可以設置解析度的,設置之後我們查看解析度:
解析度變低了,dpi也變小了。
⑤ Android兼容性適配(一)—— 設備兼容性概覽
Android 適用於眾多類型的設備,從手機到平板電腦和電視都能搭載使用。作為開發者,如此廣泛的設備類型能為您的應用帶來廣大的潛在受眾群體。為了能在所有這些設備上順利運行,應用應該容許部分設備功能的變化,並提供可適應不同屏幕配置的靈活界面。
隨著您進一步閱讀 Android 開發相關內容,您可能會在各種語境下遇到「兼容性」一詞。兼容性有兩種類型:設備兼容性和應用兼容性。
作為應用開發者,您無需擔心設備是否兼容 Android,因為只有與 Android 兼容的設備才會附帶 Google Play 商店或該設備的官方手機應用市場。因此,您可以放心,通過Google Play 商店和官方手機應用市場安裝您的應用的用戶使用的是 Android 兼容設備。
不過,您確實需要考慮您的應用是否兼容每一種可能的設備配置。由於 Android 以各種設備配置運行,因此部分功能並不適用於所有設備。例如,某些設備可能未配備羅盤感測器。如果應用的核心功能需要使用羅盤感測器,那麼應用只能與帶有羅盤感測器的設備兼容。
應用可通過平台 API 利用 Android 支持的各種功能。有些功能基於硬體(例如羅盤感測器),有些功能基於軟體(如應用窗口微件),有些功能則依賴於平台版本。並非每台設備都支持所有功能,因此您可能需要根據應用所需的功能控制應用在設備上的可用性。
要盡可能擴大應用的用戶群,您應設法使用單個 APK 支持盡可能多的設備配置。在大多數情況下,要實現這一目標,您可以在運行時停用可選功能,並為應用資源提供針對不同配置的替代選項(例如針對不同屏幕尺寸的不同布局)。不過,如果需要,您可以根據以下設備特徵,通過 Google Play 商店限制應用在設備上的可用性:
為了讓您根據設備功能管理應用的可用性,Android 為可能並不適用於所有設備的任何硬體或軟體功能定義了功能 ID。例如,羅盤感測器的功能 ID 為 FEATURE_SENSOR_COMPASS,而應用微件的功能 ID 為 FEATURE_APP_WIDGETS。
根據需要,要在用戶的設備不具備特定功能時阻止用戶安裝您的應用,您可以通過應用清單文件中的<uses-feature>元素聲明這一點。
例如,如果您的應用在沒有羅盤感測器的設備上沒有意義,您可以使用以下清單標記聲明需要羅盤感測器:
Google Play 商店會將您的應用所需的功能與每個用戶的設備上可用的功能進行比較,以確定您的應用是否與每台設備兼容。如果設備不具備您的應用所需的所有功能,則用戶無法安裝您的應用。
但是,如果應用的主要功能不需要某項設備功能,則應將required屬性設置為 "false"並在運行時檢查是否有該設備功能。如果應用功能在當前設備上不可用,請適當降級相應的應用功能。例如,您可以通過調用hasSystemFeature()來查詢功能是否可用,如下所示:
Kotlin
不同的設備可能會運行不同版本的 Android 平台,例如 Android 4.0 或 Android 4.4。每個後續的平台版本通常會添加之前版本中不可用的新 API。為表明可用的 API 集,每個平台版本都會指定API 級別。例如,Android 1.0 是 API 級別 1,而 Android 4.4 是 API 級別 19。
通過 API 級別,您可以使用<uses-sdk>清單標記及其minSdkVersion屬性來聲明應用兼容的最低版本。例如,Android 4.0(API 級別 14)中添加了 日歷提供程序 API。如果您的應用在沒有這些 API 的情況下無法運行,您應將 API 級別 14 聲明為應用的最低支持版本。
minSdkVersion屬性聲明應用兼容的最低版本,targetSdkVersion屬性聲明應用經過優化後適用的最高版本。
不過,請注意<uses-sdk>元素中的屬性會被替換為build.gradle文件中的相應屬性。因此,如果您使用的是 Android Studio,則必須在其中指定minSdkVersion和targetSdkVersion值:
要詳細了解build.gradle文件,請參閱 如何配置編譯版本 。
每個後續版本的 Android 都為使用之前平台版本的 API 構建的應用提供兼容性,因此您的應用應始終與未來版本的 Android 兼容,同時使用已記錄的 Android API。
注意 : targetSdkVersion 屬性不會阻止您的應用安裝在高於指定值的平台版本上,但它很重要,因為它向系統指示您的應用是否應繼承較新版本中的行為更改。如果您不將 targetSdkVersion 更新到最新版本,則系統會認為您的應用在最新版本上運行時需要一些向後兼容性行為。例如,在 Android 4.4 中的行為更改 中,使用 AlarmManager API 創建的鬧鍾現在默認不精確,因此系統可以批量處理應用鬧鍾並節省系統電量,但如果您的目標 API 級別低於「19」,則系統會為您的應用保留之前的 API 行為。
不過,如果您的應用使用的是較新平台版本中添加的 API,但其主要功能並不需要這些 API,則應在運行時檢查 API 級別,並在 API 級別過低時適當降級相應的功能。在這種情況下,請將 minSdkVersion 盡量設置為適用於應用主要功能的最低值,然後將當前系統的版本 SDK_INT 與 Build.VERSION_CODES 中對應於您要檢查的 API 級別的一個代號常量進行比較。例如:
Android 可在各種尺寸的設備上運行,包括手機、平板電腦和電視。為了按照屏幕類型對設備進行分類,Android 為每種設備定義了兩個特徵:屏幕尺寸(屏幕的物理尺寸)和屏幕密度(屏幕上像素的物理密度,稱為 DPI)。為了簡化不同的配置,Android 將這些變體歸納成組,使它們更容易作為定位目標:
四種廣義的尺寸:小、標准、大和特大。
還有幾種廣義的密度:mdpi(中)、hdpi(高)、xhdpi(超高)、xxhdpi(超超高)等。
默認情況下,您的應用會兼容所有屏幕尺寸和密度,因為系統會根據需要對各個屏幕的界面布局和圖片資源進行相應的調整。不過,您應針對不同的屏幕尺寸添加專門的布局,針對常見的屏幕密度添加優化的點陣圖圖片,以優化每種屏幕配置的用戶體驗。
⑥ android 屏幕適配
@[TOC](文章目錄)
<hr style=" border:solid; width:100px; height:1px;" color=#000000 size=1">
# 前言
<font color=#999AAA >使用工具Android studio,利用values文件下dimens.xml界面適配安卓屏幕</font>
<hr style=" border:solid; width:100px; height:1px;" color=#000000 size=1">
<font color=#999AAA >提示:以下是本篇文章正文內容,下面案例可供參考
# 一、概念
1.屏幕解析度單位是px,例如Android手機常見的解析度:320x480px、480x800px、720x1280px、1080x1920px。
2.手機屏幕的密度:每英寸的像素點數,單位是dpi。
| 密度類型 |代表的解析度(px)| 屏幕像素密度(dpi) | 1dp轉換為px |
|:--------|:--------|:--------|:--------|
| 低密度(ldpi) |240x320|120|0.75|
| 中密度(mdpi) |320x480|160|1|
| 高密度(hdpi)|480x800|240| 1.5|
| 超高密度(xhdpi)|720x1280|320|2|
| 超超高密度(xxhdpi) |1080x1920|480|3|
3.由於android的機型屏幕大小品類太多了,有一些是不標準的,這時我們就需要單獨去獲取屏幕的解析度和密度了。
# 二、獲取屏幕的解析度和密度
```java
DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
float density = displayMetrics.density;
int densityDpi = displayMetrics.densityDpi;
int width = displayMetrics.widthPixels;
int height = displayMetrics.heightPixels;
Log.e("123","密度:"+density+"---"+densityDpi);
Log.e("123","屏幕解析度:"+width+"x"+height);
Log.e("123","安卓系統:"+android.os.Build.VERSION.RELEASE);
Log.e("123","手錶型號:"+android.os.Build.PRODUCT);
```
# 三、SmallestWidth適配
**smallestWidth適配,或者叫sw限定符適配。指的是Android會識別屏幕可用高度和寬度的最小尺寸的dp值(其實就是手機的寬度值),然後根據識別到的結果去資源文件中尋找對應限定符的文件夾下的資源文件。**
**sw計算公式:sw = 屏幕寬度 / (dpi/160) 註:160是默認的**
**例如:屏幕寬度為1080px、480dpi 的sw = 1080/(480/160)**
# 四、生成 dimens 文件
1、 首先在 res 目錄下新建各種尺寸的 values 文件 。文件名為:values-sw(你要適配屏幕的sw值)dp。
例如:
![code23](https://img-blog.csdnimg.cn/2020111311092374.PNG#pic_center)
注意:values文件下也生成 dimens文件
**生成dimens值工具類**
1、先生成標準的值。//value = (i + 1) * 1;
2、再用生成其他的值。 //value = (i + 1) * 需要生成的sw值/標準的sw值;
例如:value = (i + 1) * 160 / 320;
```java
public static void genDimen() {
StringBuilder stringBuilder = new StringBuilder();
try {
double value;
for (int i = 0; i < 500; i++) {
//value = (i + 1) * 1; //這里控制對應轉換的值,如果是標准尺寸就一對一轉換
//value = (i + 1) * 需要生成的sw值/標準的sw值; //這里控制對應轉換的值
value = (i + 1) * 1
//value = (i + 1) * 160 / 320;
value = Math.round(value * 100) / 100;
//dp可改成sp
stringBuilder.append("<dimen name=\"size_" + (i + 1) + "\">" + value + "dp</dimen>\r\n");
}
if (stringBuilder.length() > 4000) {
for (int i = 0; i < stringBuilder.length(); i += 4000) {
if (i + 4000 < stringBuilder.length())
Log.e("123", stringBuilder.substring(i, i + 4000));
else
Log.e("123", stringBuilder.substring(i, stringBuilder.length()));
}
} else {
Log.e("123", stringBuilder.toString());
}
} catch (Exception e) {
e.printStackTrace();
} finally {
}
}
```
示例:(我這是以sw320為適配的標準的,你們可改自己的標准)
1、sw320的樣例
```java
<resources>
<dimen name="dimen_1">1.0dp</dimen>
<dimen name="dimen_2">2.0dp</dimen>
<dimen name="dimen_3">3.0dp</dimen>
<dimen name="dimen_4">4.0dp</dimen>
<dimen name="dimen_5">5.0dp</dimen>
<dimen name="dimen_6">6.0dp</dimen>
<dimen name="dimen_7">7.0dp</dimen>
<dimen name="dimen_8">8.0dp</dimen>
<dimen name="dimen_9">9.0dp</dimen>
<dimen name="dimen_10">10.0dp</dimen>
<dimen name="size_1">1.0sp</dimen>
<dimen name="size_2">2.0sp</dimen>
<dimen name="size_3">3.0sp</dimen>
<dimen name="size_4">4.0sp</dimen>
<dimen name="size_5">5.0sp</dimen>
<dimen name="size_6">6.0sp</dimen>
<dimen name="size_7">7.0sp</dimen>
<dimen name="size_8">8.0sp</dimen>
<dimen name="size_9">9.0sp</dimen>
<dimen name="size_10">10.0sp</dimen>
</resources>
```
2、sw160的樣例
```java
<resources>
<dimen name="dimen_1">0.0dp</dimen>
<dimen name="dimen_2">1.0dp</dimen>
<dimen name="dimen_3">1.0dp</dimen>
<dimen name="dimen_4">2.0dp</dimen>
<dimen name="dimen_5">2.0dp</dimen>
<dimen name="dimen_6">3.0dp</dimen>
<dimen name="dimen_7">3.0dp</dimen>
<dimen name="dimen_8">4.0dp</dimen>
<dimen name="dimen_9">4.0dp</dimen>
<dimen name="dimen_10">5.0dp</dimen>
<dimen name="size_1">0.0sp</dimen>
<dimen name="size_2">1.0sp</dimen>
<dimen name="size_3">1.0sp</dimen>
<dimen name="size_4">2.0sp</dimen>
<dimen name="size_5">2.0sp</dimen>
<dimen name="size_6">3.0sp</dimen>
<dimen name="size_7">3.0sp</dimen>
<dimen name="size_8">4.0sp</dimen>
<dimen name="size_9">4.0sp</dimen>
<dimen name="size_10">5.0sp</dimen>
</resources>
```
3、xml界面控制項使用樣例
```java
<TextView
android:layout_width="@dimen/dimen_30"
android:layout_height="@dimen/dimen_30"
android:textSize="@dimen/size_20"
android:layout_margin="@dimen/dimen_10"
android:padding="@dimen/dimen_10">
```
<hr style=" border:solid; width:100px; height:1px;" color=#000000 size=1">
# 總結
<font color=#999999 >提示:這里對文章進行總結:
如果你的app需要適配dpi較低的屏幕,最好以最小dpi的sw為適配的標准。
⑦ Android平板應用適配
首先是尺寸的適配,android平板和手機相比,由於pad的大屏特性,屏幕的尺寸和解析度的差別就很明顯,例如以下平板信息:
小米平板:4.4.4 densityDpi:320 size:1536x2048
華為平板:5.1.1 densityDpi:240 size:1200x1920
華為榮耀某平板:6.1 densityDpi:320 size:1200x1920
三星平板:6.0.1 densityDpi:320 size:1600x2560
同樣的一套mdpi下的layout或者values放在上面華為榮耀平板和三星平板上顯示差別就很大。下面是開發中關於設計的一些心得:
1. 開發中保持不增加布局層級的情況下採用百分比weight屬性;針對不同尺寸的設備百分比縮放是體驗最完美的,但由於實際開發中復雜界面如果採用百分比,無疑增加了層級復雜度,反而降低了性能,降低了可維護性和擴展性。
2. layout中使用的dp/sp值採用@dimen引用方式寫進dimens.xml裡面;為了方便採用多個values文件夾例如values-sw600dp,values-1280x720等針對特定屏幕適配。自然也可以採用layout-1280x720這樣的來區分不同布局,但如果只是尺寸上的適配,無疑用dimens維護幾套尺寸值是最容易的,還可以寫個讀寫文件工具,修改一個values里的dimens文件後更新到所有的values文件;
3. 以上面的華為榮耀平板為例,採用sw(smallwidth)的方式進行適配,比較簡單的計算方式,以mdpi(160)為標准,此平板的screenWidthDips = 1200/(320/160) = 600dp,所以values-sw600dp可以適配此平板(有的平板系統寬高是包含屏幕的虛擬按鍵的高度);
4. 為了苛求在不同尺寸平板上的體驗,採用values-1200x1920,values-1600x2560這種方式,即為每個屏幕增加尺寸適配,工作量和效率來說不會影響太大,畢竟可以通過軟體工具生成多套;
除了界面方面,平板開發上的模塊化採用Fragment更多,以及Fragment嵌套Fragment:
5. Fragment中調用startActivityForResult,如果要在Fragment的onActivityResult里回調處理,那麼不要採用getActivity().startActivityForResult方法,且宿主Activity如果重寫了onActivityResult方法的,必須調用super.onActivityResult,否則Fragment的onActivityResult方法不會回調,這點可以從Activity的源碼中看出來;
6. 嵌套在Fragment里的子Fragment的onActivityResult如果需要回調則要自己處理;
7. Fragment嵌套Fragment時,在Fragment里採用getChildFragmentManager()管理子Fragment,用法跟getSupportFragmentManager()一樣;子Fragment之間的通信,可以採用事件匯流排方案進行解耦,例如Otto/EventBus,但可讀性會下降,所以詳細的注釋還是必要的;