本文方案为修改系统density
- px---------->像素
- dpi---------->像素密度 对应于DisplayMetrics类中属性densityDpi的值 dpi = density*160
- density----->屏幕密度 px = dpi*density
Android系统最终会将xml中dp,sp值转换为像素px。通常情况下ui给到我们设计图的单位是px,以设计图最大宽度为参照值,根据屏幕最大宽度算出比例,将得到的值替换系统density。
打个比方:设计图最大宽度500px,手机最大宽度720px,density修改为720/500=1.44。在xml中指定view的宽度为250dp,系统计算得到view宽度250*density=360px。正好占据手机宽度720px的一半,与设计图相符。
以此类推:另一台手机最大宽度1080px,density修改为1080/500=2.16。此时计算得到view宽度250*2.16=540px,正好占据宽度一半。
也就是说根据手机屏幕宽度像素点的不同,依照设计图最大宽度,动态修改系统density值,然后按设计图指定view大小,在不同分辨率设备上表现是一致的。
object AutoSize {
private var density: Float = 0F//屏幕密度
private var scaleDensity: Float = 0F//字体缩放比例
//设计图宽度默认为500px
@JvmOverloads
fun init(activity: Activity, width: Float = 500F) {
val displayMetrics = activity.resources.displayMetrics
//系统屏幕密度
density = displayMetrics.density
//系统字体缩放比例
scaleDensity = displayMetrics.scaledDensity
//计算适配屏幕密度、字体缩放比例、像素密度
val currentDensity = displayMetrics.widthPixels / width
val currentScaleDensity = currentDensity * (scaleDensity / density)
val currentDensityDpi = (currentDensity * 160).toInt()
//替换系统值
val dm = activity.resources.displayMetrics
dm.density = currentDensity
dm.scaledDensity = currentScaleDensity
dm.densityDpi = currentDensityDpi
}
}
在setContentView前调用
class AutoSizeActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
AutoSize.init(this)
setContentView(R.layout.activity_autosize)
}
}
activity_autosize.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="250dp"
android:layout_height="250dp"
android:background="@android:color/holo_orange_dark"
android:gravity="center"
android:text="text"
android:textSize="20sp" />
</RelativeLayout>
运行
可以在BaseActivity中调用,也可以在Application中操作
class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
registerActivityLifecycleCallbacks(object : ActivityLifecycleCallbacks {
override fun onActivityPaused(activity: Activity) {
}
override fun onActivityStarted(activity: Activity) {
}
override fun onActivityDestroyed(activity: Activity) {
}
override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {
}
override fun onActivityStopped(activity: Activity) {
}
override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
AutoSize.init(activity)
}
override fun onActivityResumed(activity: Activity) {
}
})
}
}
如果某些Activity不希望适配,写个空接口
interface CancelAdapter
Activity实现接口
class AutoSizeActivity : AppCompatActivity(), CancelAdapter {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_autosize)
}
}
Application
class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
registerActivityLifecycleCallbacks(object : ActivityLifecycleCallbacks {
override fun onActivityPaused(activity: Activity) {
}
override fun onActivityStarted(activity: Activity) {
}
override fun onActivityDestroyed(activity: Activity) {
}
override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {
}
override fun onActivityStopped(activity: Activity) {
}
override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
if (activity is CancelAdapter) return
AutoSize.init(activity)
}
override fun onActivityResumed(activity: Activity) {
}
})
}
}
某些Activity设计图大小不一致,添加新接口
interface CustomizeAdapter {
fun getWidth(): Float
}
Activity实现接口
class AutoSizeActivity : AppCompatActivity(), CustomizeAdapter {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_autosize)
}
override fun getWidth(): Float {
return 750F
}
}
Application
class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
registerActivityLifecycleCallbacks(object : ActivityLifecycleCallbacks {
override fun onActivityPaused(activity: Activity) {
}
override fun onActivityStarted(activity: Activity) {
}
override fun onActivityDestroyed(activity: Activity) {
}
override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {
}
override fun onActivityStopped(activity: Activity) {
}
override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
when (activity) {
is CancelAdapter -> return
is CustomizeAdapter -> {
AutoSize.init(activity, activity.getWidth())
}
else -> AutoSize.init(activity)
}
}
override fun onActivityResumed(activity: Activity) {
}
})
}
}
占据三分之一宽度
感觉有点像AndroidAutoSize,怎么肥事=。=
网友评论