屏幕適配.png
關(guān)于屏幕適配袖扛,我們先來看下官方文檔上說了些什么宵喂!
????????????
屏幕適配:文檔上翻譯為屏幕兼容性
- 必須遵循的核心原則是避免對界面組件的位置和大小進(jìn)行硬編碼秉剑。應(yīng)該允許拉伸視圖尺寸并指定視圖相對于父視圖或其他同級視圖的位置砰碴。
- 像素密度是屏幕上單位面積內(nèi)的像素數(shù),稱為 dpi(每英寸的點數(shù))蒜魄。它與分辨率不同巷燥,后者是屏幕上像素的總數(shù)赡盘。
- 使用像素來定義布局尺寸會帶來問題,因為不同的屏幕具有不同的像素密度缰揪,因此同樣數(shù)量的像素在不同設(shè)備上可能對應(yīng)于不同的物理尺寸。
- dp 是一種密度無關(guān)像素葱淳,對應(yīng)于 160 dpi 下像素的物理尺寸钝腺。 sp 是相同的基本單位,但它會按用戶首選的文本尺寸進(jìn)行縮放(屬于縮放無關(guān)像素)赞厕,因此在定義文本尺寸時應(yīng)使用此計量單位(但切勿為布局尺寸使用該單位)艳狐。
dpi(來源于官方視頻).png
部分截圖.png
以上選取的是官方文檔中屏幕兼容性的主要內(nèi)容∶笊#或許正是受了文檔的指向毫目,在之前我們大多數(shù)的屏幕適配方案都采用最小寬度限定符的方式(更早之前采用寬高限定符)蔬啡;另一方面,隨著劉海屏镀虐、全面屏不斷的引入市場箱蟆,碎片化越來越重。導(dǎo)致最小寬度限定符適配越來越沉重刮便。因此新的適配方案應(yīng)運而生空猜,今日頭條的屏幕適配方案??將這個問題重新拉回視線。
關(guān)于其原理恨旱,文章中已經(jīng)說的很清楚了辈毯。簡單來講,就是固定的一個維度搜贤,重新獲取density的值(density = 設(shè)備真實寬(單位px) / UI設(shè)計圖寬)谆沃。上代碼??。
/**
* 今日頭條方案----核心代碼(仍需擴(kuò)展)
* Android適配:修改設(shè)備密度
*/
public class DisplayUtil {
//UI提供的設(shè)計圖尺寸
private static final int UI_MEASURE = 360;
private static float sNoncompatDensity;
private static float sNoncompatScaledDensity;
public static void setCustomDensity(@NonNull Activity activity, @NonNull final Application application) {
//獲取DisplayMetrics對象
DisplayMetrics appDisplayMetrics = application.getResources().getDisplayMetrics();
if (sNoncompatDensity == 0) {
//獲取density密度
sNoncompatDensity = appDisplayMetrics.density;
//獲取scaledDensity--字體的縮放因子
sNoncompatScaledDensity = appDisplayMetrics.scaledDensity;
// 防止系統(tǒng)切換后不起作用--如果在系統(tǒng)設(shè)置中切換字體仪芒,再返回應(yīng)用唁影,字體并沒有變化
application.registerComponentCallbacks(new ComponentCallbacks() {
@Override
public void onConfigurationChanged(Configuration newConfig) {
if (newConfig != null && newConfig.fontScale > 0) {
sNoncompatScaledDensity = application.getResources().getDisplayMetrics().scaledDensity;
}
}
@Override
public void onLowMemory() {
}
});
}
float targetDensity = appDisplayMetrics.widthPixels / UI_MEASURE;
// 防止字體變小
// 某些用戶在系統(tǒng)中修改了字體大小失效了,但是不能直接用原始的scaledDensity桌硫,直接用的話可能導(dǎo)致某些文字超過顯示區(qū)域
float targetScaleDensity = targetDensity * (sNoncompatScaledDensity / sNoncompatDensity);
int targetDensityDpi = (int) (160 * targetDensity);
/**
* 設(shè)置application中的值
*/
appDisplayMetrics.density = targetDensity;
appDisplayMetrics.scaledDensity = targetScaleDensity;
appDisplayMetrics.densityDpi = targetDensityDpi;
/**
* 設(shè)置activity中的值
*/
final DisplayMetrics activityDisplayMetrics = activity.getResources().getDisplayMetrics();
activityDisplayMetrics.density = targetDensity;
activityDisplayMetrics.scaledDensity = targetScaleDensity;
activityDisplayMetrics.densityDpi = targetDensityDpi;
}
}
目前項目中采用的方案為最小寬度限定符夭咬。其優(yōu)勢,就是穩(wěn)定铆隘,不會出現(xiàn)較大的問題卓舵。目前常用sw文件有:xhdpi(320)、360膀钠、400掏湾、411、420肿嘲、xxhpdi(480)融击、560...[hdpi(240\可選)]。
參考鏈接:
https://developer.android.com/guide/practices/screens_support
http://www.reibang.com/p/b6b9bd1fba4d
http://www.reibang.com/p/1302ad5a4b04
http://www.reibang.com/p/55e0fca23b4f?utm_source=oschina-app
https://juejin.im/post/5c18039d5188253b7e74987e