android屏幕适配density,Android开发一步到位屏幕适配解决方案

本文分享了一种针对Android屏幕适配的解决方案,通过设定基准屏幕参数和放大缩小比例,实现不同尺寸屏幕的适配,保证布局在大屏和小屏上的一致性。关键步骤包括计算放大缩小比率、确定参考屏幕密度和设置相对屏幕密度。这种方法旨在减少多套图片和布局的使用,简化维护工作,并优化apk大小。
摘要由CSDN通过智能技术生成

看简书上和CSDN都没有一篇特别有针对性的Android屏幕适配解决方案,大部分都是基于官方的基本的,或者挪来挪去的,最近自己刚好处理一个老项目需要适配大小屏,这里就贴一个自己的屏幕适配解决方案,有问题大家一起沟通。

大家都知道Android屏幕适配是件非常头疼的事,目前全世界安卓设备的大大小小分辨率,大大小小的尺寸,最终形成的设备屏幕大小种类不计其数,但就这一项就给开发者造成了不少困难,总是照顾住这种屏幕照顾不了那种屏幕。

先来放一种很熟悉的图:

AAffA0nNPuCLAAAAAElFTkSuQmCC

image

针对Android屏幕适配,除了我们按照“灵活运用布局”、“尺寸限定符”、“布局相关属性”、“.9图”、“屏幕密度适配”等官方标准,但是却发现还远远不够,要么添加很多图片(从加载性能说似乎是必要的)使得apk变得很大,要么有多套布局工作量变大难以维护。针对屏幕适配,google官方也是系统默认支持的是采用屏幕像素密度来进行匹配相关资源和长度的,这一块不做过多的阐述了,建议参看官方文档。

大概其优点如下:只需要提供一套最优图片,用于减小apk包大小。当然为了加载性能和图片更精细化显示采用多套也可以。

无论大小屏如果布局确定只需要一套布局,当然如果横竖屏变换不同的屏幕展示,多套也是必要的。

没有重叠的现象发生,按照默认布局方法可能在大屏上适配很好,到小屏上却出现重叠的现象,很常见,但这里我不允许他有!

无论大小屏整体看过去布局几乎相同,因为是按比例来的。

在大屏上展示不会随着完全比例放大而显得傻、大、憨。

其原理也很简单,就是根据基准屏幕像素密度来进行适当缩放后得到相对屏幕像素,然后给系统的像素密度重新赋值。

准备工作:

确定一套基准屏幕参数,然后布局时根据这套参数布局,单位仍然采用dp,并尽可能确定其布局控件的长度。//绘制页面时参照的设计图尺寸

final float DESIGN_WIDTH = 1080f;        final float DESIGN_HEIGHT = 1920f;        final float DESTGN_INCH = 5.0f;

三步走:确定放大缩小比例

确定参考屏幕密度

确定相对屏幕密度并重新赋值给系统的像素密度

主要方法:/**

* 重置屏幕密度

*/

public static void resetDensity(Context context) {        //绘制页面时参照的设计图尺寸

final float DESIGN_WIDTH = 800f;        final float DESIGN_HEIGHT = 1280f;        final float DESTGN_INCH = 5.0f;        //大屏调节因子,范围0~1,因屏幕同比例放大视图显示非常傻大憨,用于调节感官度

final float BIG_SCREEN_FACTOR = 0.8f;

DisplayMetrics dm = context.getResources().getDisplayMetrics();        //确定放大缩小比率

float rate = Math.min(dm.widthPixels, dm.heightPixels) / Math.min(DESIGN_WIDTH, DESIGN_HEIGHT);        //确定参照屏幕密度比率

float referenceDensity = (float) Math.sqrt(DESIGN_WIDTH * DESIGN_WIDTH + DESIGN_HEIGHT * DESIGN_HEIGHT) / DESTGN_INCH / DisplayMetrics.DENSITY_DEFAULT;        //确定最终屏幕密度比率

float relativeDensity = referenceDensity * rate;        if (ORIGINAL_DENSITY == -1) {

ORIGINAL_DENSITY = dm.density;

}        if (relativeDensity > ORIGINAL_DENSITY) {

relativeDensity = ORIGINAL_DENSITY + (relativeDensity - ORIGINAL_DENSITY) * BIG_SCREEN_FACTOR;

}

dm.density = relativeDensity;

dm.densityDpi = (int) (relativeDensity * DisplayMetrics.DENSITY_DEFAULT);

dm.scaledDensity = relativeDensity;

}

上边放大缩小比例是根据屏幕的长宽和参考屏幕的长宽对应设定的,这样计算出来的屏幕密度是固定的。

注意最终赋值的三个成员变量的含义:dm.density

屏幕密度比率,不同设备的屏幕视图的长宽大小都是根据屏幕密度比率与屏幕密度基准值(160dp)的乘积。此成员变量控制拥有固定长宽值视图的缩放。

dm.densityDpi

实际屏幕密度比率,但是单独设定此值并不一定起到缩放效果,需要配合density一起设定,此成员变量控制长宽自动wrapConent形式的缩放,因为wrapContent形式下系统自动为其分配默认的屏幕密度,如果不对其重新赋值,则不能根据规则进行缩放。

dm.scaledDensity

独立像素密度,主要处理字体大小缩放,目前比较流行的字体单位为dp,第一能随着应用适应不同的设备缩放,第二避免了跟随系统缩放使得布局展示错乱。但是某些系统机开发者不能控制的例如toast字体大小等默认使用的单位仍然是sp,所以此成员变量也需要进行重新赋值。系统默认应用sp和dp二者的比率为1,但是某些情况下又想根据系统缩放,还要保持整体缩放比率,这是就要系统缩放和应用缩放结合着得出一个比率来最终赋值了。

配置地方:

DisplayMetrics相关参数的值有两种,一种是默认的,一种是动态调整后的。

获取默认的:DisplayMetrics display = new DisplayMetrics();

getWindowManager().getDefaultDisplay().getMetrics(display);

获取动态调整后的:DisplayMetrics dm = context.getResources().getDisplayMetrics();

应用展示最终使用的DisplayMetrics相关参数就是调整后的。android8.0之前,整个应用长宽缩放比率均是采用一套,无论时Activity和Application两者任意其一配置均可,但是在Android8.0的时候,系统架构调整,由原来的统一现在重点分配到每个Activity中和Application中,为了兼顾全局,两者都要设置,尤其是Activity。Activity中设置的时候要注意一定要设置在setContentView()之前,Application设置在onCreat()即可。

还应注意一点,当屏幕旋转时有时我们为了保存相关状态,所以不想让Activity的onCreat()方法重走一遍,但是屏幕旋转会使得屏幕密度参数进行重置,不得已我们还要在屏幕旋转的时候在重新设置一下屏幕密度。

源码中屏幕旋转所作的工作:@Override

public void onConfigurationChanged(Configuration newConfig) {        super.onConfigurationChanged(newConfig);

getDelegate().onConfigurationChanged(newConfig);        if (mResources != null) {            // The real (and thus managed) resources object was already updated

// by ResourcesManager, so pull the current metrics from there.

final DisplayMetrics newMetrics = super.getResources().getDisplayMetrics();

mResources.updateConfiguration(newConfig, newMetrics);

}

}

作者:toperc

链接:https://www.jianshu.com/p/4baa82130a9f

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值