作为一名Android Developer,有一个“顽疾”一直都无法绕开,那就是屏幕适配,毕竟Android自由的同时,也引入了很多“奇奇怪怪”的东西,比如各种各样的屏幕大小/分辨率等等,也就是导致了作为应用开发者,必须思考如何让自己的应用正常适配更多的机型。本文主要介绍一些关于屏幕显示的基本概念,以及目前主流的屏幕适配思想。
基础知识
获取DisplayMetrics
1 | //Display屏幕显示的详细信息 |
修改DisplayMetrics
上面获取的DisplayMetrics只可读,如下是在APP中修改displayMetrics来动态适配的。
1 | //修改屏幕density |
通过以上代码,基本上对图片和字体都能完美适配了,但是对于代码创建的bitmap还是会有问题,bitmap创建时默认会使用系统的density, 我们需要创建的时候指定我们修改后的displayMetrics
1 | Bitmap bitmap = Bitmap.createBitmap(displayMetrics,width,height,config); |
或者在创建完成后手动调用bitmap的setDensity方法修改density
1 | bitmap.setDensity(DisplayMetrics.DENSITY_MEDIUM); |
DisplayMetrics信息
widthPixels:屏幕宽度;
heightPixels:屏幕高度;
densityDpi:屏幕密度,每英寸的像素数;
density:密度比值,其实就是densityDpi/160得出来的值(160密度就是谷歌定的一个密度标准),不同手机dp换算px就是通过该值;
scaledDensity:同density,用于文字缩放的计算,也就是sp;
xDpi:水平方向的真实密度;
yDpi:垂直方向的真是密度;
适配方案
对于适配方案,目前主要有两种思想:
对于不同分辨率,可以做到相同的缩放比,即显示内容一样,比如下图:
对于不同的屏幕,屏幕越大显示更多的内容,如下图:
两种方案没有优劣,只有适合的业务场景!!!下面我们重点提一下第一种思路,介于这个问题在伴随着Android成长的过程就开始逐渐被思考解决,方案基本成熟,所以选择了一种使用比较广泛的给大家科普一下,也方便自己记忆。
AndroidAutoSize
由 JessYanCoding根据之前今日头条屏幕适配方案的改进版,是一个非常优秀的、极低成本的 Android 屏幕适配方案,属于我们上面提到的前者,具体的内容详见github;
基本原理:
1 | 当前设备屏幕总宽度(单位为像素)/ 设计图总宽度(单位为 dp) = density |
density 的意思就是 1 dp 占当前设备多少像素,
核心点就是将设计图的dp转化成根据不同屏幕的density计算得到的px值,关于这个公式的计算,是在app 的 AndroidManifest.xml 填写设计图的宽高dp值,然后声明一个 ContentProvider,在它的 onCreate 方法中启动框架即可,在 App 启动时,系统会在 App 的主进程中自动实例化你声明的这个 ContentProvider,并调用它的 onCreate 方法,执行时机比 Application#onCreate 还靠前,可以做一些初始化的计算工作,比如动态的设置DisplayMetrics的density值。这样其实在开发过程中,你只需要按照设计图中规定的dp值,设定相应的控件即可,