美文网首页
Android 屏幕适配原理

Android 屏幕适配原理

作者: 折剑游侠 | 来源:发表于2020-06-02 17:42 被阅读0次

    本文方案为修改系统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,怎么肥事=。=

    相关文章

      网友评论

          本文标题:Android 屏幕适配原理

          本文链接:https://www.haomeiwen.com/subject/agguzhtx.html