前言:螢屏適配說白了就是將設計圖按寬或高進行整體等比縮放,
方案:如設計圖解析度(寬360px,高560px),手機屏分別率(寬1080px,高1920px),按寬進行適配需要將設計圖的控制元件尺寸寬高等比放大(手機屏寬1080px / 設計圖寬360px = 3)倍,而獲取xml中定義的所有控制元件再分別對寬高放大3倍,這操作我們通過代碼實作,顯然很繁重,然而我就將這部分作業交給系統,要知道控制元件在系統中寬高最終都轉成px(px= density * dp),我們就巧妙利用系統的轉換公式,將density = 手機屏寬 / 設計圖寬,在xml中直接將設計圖px值作為dp值使用即可(如設計圖控制元件寬360px,那么xml中寬定義為360dp),同理按高適配只需將density = 手機屏高 / 設計圖高,在xml中使用dp系統則自行進行縮放,如果有的頁面需要按寬有的頁面需要按高適配或同一頁面不同控制元件有的需按高適配有的需按高適配,我們可以利用(px = xdpi / 72 * pt)將xdpi = 手機屏高 / 設計圖高 * 72,xml中將需要按高度適配的控制元件寬高定義成pt,按寬度適配的控制元件寬高定義成dp即可,
實作:只需在application的onCreate方法中呼叫ScreenUtil的init方法即可
object ScreenUtil {
fun init(application: Application, designWith: Float, designHeight: Float){
val appDisplayMetrics = application.resources.displayMetrics
val screenWith = appDisplayMetrics.widthPixels //螢屏寬度px
val screenHeight = appDisplayMetrics.heightPixels //螢屏高度px
val densityDef = appDisplayMetrics.density //系統默認density
appDisplayMetrics.density = screenWith / designWith
appDisplayMetrics.densityDpi = (appDisplayMetrics.density * 160).toInt()
appDisplayMetrics.xdpi = designHeight / screenHeight * 72
//字體跟隨系統設定,默認scaleDensity==density
appDisplayMetrics.scaledDensity = appDisplayMetrics.density * (appDisplayMetrics.scaledDensity / densityDef)
//監聽系統字體切換
application.registerComponentCallbacks(object : ComponentCallbacks{
override fun onLowMemory() {}
override fun onConfigurationChanged(newConfig: Configuration?) {
newConfig?.let {
if (it.fontScale > 0){
appDisplayMetrics.scaledDensity = appDisplayMetrics.density * (appDisplayMetrics.scaledDensity / densityDef)
}
}
}
})
//activity生命周期監聽
application.registerActivityLifecycleCallbacks(object : Application.ActivityLifecycleCallbacks{
override fun onActivityCreated(activity: Activity?, savedInstanceState: Bundle?) {
activity?.let {
val activityDisplayMetrics = it.resources.displayMetrics
activityDisplayMetrics.density = it.application.resources.displayMetrics.density
activityDisplayMetrics.scaledDensity = it.application.resources.displayMetrics.scaledDensity
activityDisplayMetrics.densityDpi = it.application.resources.displayMetrics.densityDpi
activityDisplayMetrics.xdpi = it.application.resources.displayMetrics.xdpi
}
}
override fun onActivityPaused(activity: Activity?) {}
override fun onActivityResumed(activity: Activity?) {}
override fun onActivityStarted(activity: Activity?) {}
override fun onActivityDestroyed(activity: Activity?) {}
override fun onActivitySaveInstanceState(activity: Activity?, outState: Bundle?) {}
override fun onActivityStopped(activity: Activity?) {}
})
}
}
補充說明:
1、字體大小由scaledDensity控制,默認scaledDensity==density,當用戶修改系統字體后scaledDensity縮放至(當前的scaledDensity / 系統默認density)倍,如無需字體跟隨系統設定可直接將scaledDensity設定為density同時也無需監聽系統字體切換
2、density=dpi*160 dpi為軟體層面在系統組態檔定義的值,而ppi為物理層面一英寸對應的像素值
3、寬高限定符適配方案(需要定義需要適配的機型解析度):values-800x480 如果手機螢屏解析度不滿足我們定義的將使用默認的values
4、sw限定符適配(需要定義需要適配的機型寬度dp):values-sw350dp 如果手機螢屏dp不滿足我們定義的系統會向下尋找最近的資源檔案
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/222949.html
標籤:python
上一篇:iOS開發Playground檔案運行Running卡住問題
下一篇:188.m1-代碼整合
