很想和你們嘮叨幾句突雪,聊聊入行后我下移的發(fā)際線是怎么做到的什黑!奈何不善言談崎淳,雖心有千言萬語,竟只能對著屏幕嘆一聲下次再聊愕把。
本人學(xué)識有限拣凹,錯(cuò)誤之處還望各位大佬斧正。[]( ̄▽ ̄)*下面進(jìn)入正題恨豁。
1.使用dp嚣镜、sp、wrap_content橘蜜、match_parent
2.布局中使用weight或者ConstraintLayout等靈活布局
3.通配符適配菊匿,如:layout-sw320dp、values-sw320dp
4.頭條方案
使用1计福、2兩種方法跌捆,也是我們開發(fā)中最常用的方法,基本能滿足我們大部分(80%左右)機(jī)型的適配棒搜,但是還有小部分的機(jī)型顯示會(huì)出現(xiàn)問題疹蛉,這時(shí)候我們就要用到了3活箕、4兩種方法的一種力麸。
通配符
先來說說通配符,通配符適配是Google早期為了能讓APP能同時(shí)適配手機(jī)和平板而提供的功能育韩,后被用于解決Android手機(jī)屏幕尺寸碎片化引起的適配問題克蚂。
通配符的格式:文件名+通配符限制,中間用“-”連接筋讨。
我們常用的分辨率適配:drawbale-1920*1080埃叭、drawbale-1280*720等
寬度適配:values-sw320dp、values-sw360dp等
├── src/main
│ ├── res
│ ├── ├──values
│ ├── ├──values-sw320dp
│ ├── ├──values-sw360dp
│ ├── ├──values-sw400dp
│ ├── ├──values-sw411dp
│ ├── ├──values-sw480dp
│ ├── ├──...
│ ├── ├──values-sw600dp
│ ├── ├──values-sw640dp
上面是我公司項(xiàng)目使用的通配符適配目錄悉罕。是不是很熟悉赤屋?沒錯(cuò)跟狱,這個(gè)基本是個(gè)固定的目錄格式味榛,已經(jīng)有大神幫我設(shè)計(jì)好了,我們只要照搬這個(gè)目錄就可以了篓像。(你要是覺的不夠精細(xì)嗜逻,可以自己增加 ̄▽ ̄)既然我們用了通配符涩僻,那么values中的dimens.xml想必是不一樣(*^▽^*),下面我舉個(gè)例子來說明dimens中值是怎么計(jì)算出來的!
假設(shè)UI給的設(shè)計(jì)圖尺寸是1280*750逆日,我要計(jì)算的是sw320dp-》dimens
屏幕寬度320dp嵌巷、設(shè)計(jì)圖750px,
如果要把屏幕占滿我們需要設(shè)置view的寬度為320dp或者750px室抽、
如果占一半view的寬度為160dp或者375px搪哪、
依次類推我們能看出dp和px之間的比例是固定的320/750=160/375....=0.43。也就是說1px=0.43dp坪圾∝溃總體來看就是我們把320dp的屏幕分成了750份,用每份來替換dp值(如:1px(pb_px_1)=0.43dp)神年。
<dimen name="base_dpi">320dp</dimen>
<dimen name="qb_px_0">0.00dp</dimen>
<dimen name="qb_px_1">0.43dp</dimen>
<dimen name="qb_px_2">0.85dp</dimen>
<dimen name="qb_px_3">1.28dp</dimen>
<dimen name="qb_px_4">1.71dp</dimen>
<dimen name="qb_px_5">2.13dp</dimen>
<dimen name="qb_px_6">2.56dp</dimen>
<dimen name="qb_px_7">2.99dp</dimen>
<dimen name="qb_px_8">3.41dp</dimen>
<dimen name="qb_px_9">3.84dp</dimen>
...
<dimen name="qb_px_719">306.77dp</dimen>
<dimen name="qb_px_720">307.20dp</dimen>
...
<dimen name="qb_px_750">320dp</dimen>
同理已维,sw360dp也是把屏幕分成750份、每份360/750=0.48
Android Studio自動(dòng)生成dimens插件下載
由于Android的碎片化已日,會(huì)有各種稀奇古怪的手機(jī)寬度是上面沒有的通配寬度垛耳,(sw -> small width 最小寬度通配符) ,遇到這種情況系統(tǒng)會(huì)自動(dòng)幫我想下查找最近的通配寬度飘千。
假如有一臺(tái)340dp的手機(jī)堂鲜,而我們的統(tǒng)配符有沒有340dp,那么會(huì)自動(dòng)先下查找到并使用sw320dp的參數(shù)护奈。但是我們手機(jī)的寬度明明是340dp缔莲,卻用的320dp的參數(shù),這不是產(chǎn)生了誤差霉旗。沒錯(cuò)痴奏,但是這種誤差基本可以忽略,下面我們來簡單算算厌秒。
340/750=0.45
320/750=0.43
如果一個(gè)view的高度是30dp读拆,那么兩者的誤差為0.6dp,0.6/30*100=2%
一個(gè)30dp的view鸵闪,誤差小于1dp(2%)檐晕,這點(diǎn)差異完全可以忽略,顯示效果用眼睛看不出差異蚌讼。
所以通過增加通配符各種不同的尺寸辟灰,能讓我們的UI適配更完善。但是篡石,相應(yīng)的也會(huì)增加app的體積芥喇。
小結(jié):
優(yōu)點(diǎn):兼容性好、無性能消耗夏志、
缺點(diǎn):侵入高
ps:因?yàn)榇a遺留問題乃坤,我公司app中的dimens中的計(jì)算錯(cuò)誤苛让,造成現(xiàn)在只能將錯(cuò)就錯(cuò),如果修改dimens湿诊,整個(gè)app的布局參數(shù)都要改...想想就頭皮發(fā)麻
頭條方案
先來看看幾個(gè)公式:
- 屏幕寬度(px) = 屏幕(設(shè)計(jì)圖)寬度(dp)* density狱杰;
- density = dpi / 160;
- dpi =對角線長度(px)/對角線長度(英寸)
假如我們的手機(jī)分辨率為1920*1080厅须、5寸仿畸,則像素密度為2203/5=440dpi
通過上面公式我們能得出:屏幕寬度 1080/(440/160)=392.7dp
實(shí)際寬度392dp,但是我們設(shè)計(jì)圖是360dp朗和,所以實(shí)際顯示效果要比UI要小错沽。
1080px是屏幕的寬度,不可改變眶拉,為了讓寬度是360dp千埃,我們只能統(tǒng)通過修改density是寬度維持在360dp。
到這里你應(yīng)該看出來我們要修改的是density指忆植,沒錯(cuò)頭條的方案就是修改系統(tǒng)的density放可。
代碼很簡單,下面貼出來朝刊。
public void setCustomDensity(Application application, Activity activity){
DisplayMetrics appDisplayMetrics = application.getResources().getDisplayMetrics();
DisplayMetrics activityDisplayMetrics = activity.getResources().getDisplayMetrics();
scaledDensity = appDisplayMetrics.scaledDensity;
density = appDisplayMetrics.density;
registerComponentCallbacks(new ComponentCallbacks() {
@Override
public void onConfigurationChanged(Configuration newConfig) {
if (newConfig != null && newConfig.fontScale > 0) {
scaledDensity = getResources().getDisplayMetrics().scaledDensity;
}
}
@Override
public void onLowMemory() {
}
});
float targerDensity = appDisplayMetrics.widthPixels / 360;
float targerScaleDensity = targerDensity * (scaledDensity / density);
int targerDpi = (int) (targerDensity * 160);
appDisplayMetrics.density = targerDensity;
appDisplayMetrics.scaledDensity = targerScaleDensity;
appDisplayMetrics.densityDpi = targerDpi;
activityDisplayMetrics.density = targerDensity;
activityDisplayMetrics.scaledDensity = targerScaleDensity;
activityDisplayMetrics.densityDpi = targerDpi;
}
小結(jié):
優(yōu)點(diǎn):沒有性能消耗耀里、侵入低
缺點(diǎn):沒什么明顯的缺點(diǎn)
3、4兩種方案在適配效果上都相當(dāng)不俗拾氓,完全能滿足大部分公司的適配需求冯挎。作為開發(fā)者我們選哪個(gè)呢?嘿嘿咙鞍,怎么選擇看個(gè)人意愿啦房官,兩者沒有優(yōu)劣之分。