目录
一、为什么要适配
二、几个重要的概念
2.1 屏幕尺寸
2.2 屏幕分辨率
2.3 屏幕像素密度
2.4 屏幕尺寸、分辨率、像素密度三者关系
三、常用单位
3.1 密度无关像素(dp)
3.2 独立比例像素(sp)
3.3 dp与px的转换
四、解决方案
4.1 今日头条
4.2 ScreenMatch适配
4.2.1 下载插件
4.2.2 使用
4.2.3 「自定义values文件」
4.3 选择适配方案->今日头条
官方文档-屏幕兼容性概览
一、为什么要适配
由于Android系统的开放性,OEM厂商、运营商都可以对Android进行定制,于是导致运行 Android 的设备多种多样,它们有着不同的屏幕尺寸和像素密度。
尽管系统可通过基本的缩放和调整大小功能使界面适应不同屏幕,但你应做出进一步优化,以确保界面能够在各类屏幕上美观地呈现。
例如UI以375px宽度来设计,如果你直接使用1dp=1px的这种方式来写代码,那么在不同屏幕的手机上面的显示可能是不一样的,这就需要你来做适配。
二、几个重要的概念
2.1 屏幕尺寸
屏幕尺寸指屏幕的对角线的长度,单位是英寸(inch),1英寸=2.54厘米
比如常见的屏幕尺寸有:4.7寸、5寸、5.5寸、6寸等。
还有一些特殊屏幕尺寸,例如Redmi K40:6.67英寸。
这个一般在设置关于手机中查看自己的屏幕尺寸。
2.2 屏幕分辨率
屏幕分辨率是指在横纵向上的像素点数,单位是px,1px=1个像素点。一般以「纵向像素x横向像素,如1080x2400」。表示宽度方向上有1080个像素点,在高度方向上有2400个像素点
单位:px(pixel),1px=1像素点。Android手机常见的分辨率:480x800、720x1280、1080x1920
UI设计师的设计图会以px作为统一的计量单位
2.3 屏幕像素密度
屏幕像素密度是指每英寸上的像素点数,单位是dpi,即"dot per inch"的缩写。
屏幕像素密度与屏幕尺寸和屏幕分辨率有关,在单一变化条件下,屏幕尺寸越小、分辨率越高,像素密度越大,反之越小。
假设设备内每英寸有160个像素,那么该设备的屏幕像素密度=160dpi
安卓手机对于每类手机屏幕大小都有一个相应的屏幕像素密度:
密度类型 | 代表的分辨率(px) | 屏幕像素密度(dpi) |
---|---|---|
低密度(ldpi) | 240x320 | 120 |
中密度(mdpi) | 320x480 | 160 |
高密度(hdpi) | 480x800 | 240 |
超高密度(xhdpi) | 720x1280 | 320 |
超超高密度(xxhdpi) | 1080x1920 | 480 |
2.4 屏幕尺寸、分辨率、像素密度三者关系
像素密度(dpi) =宽高/屏幕大小。
例如:屏幕分辨率为1080x2400,屏幕尺寸为6.67来计算。
1. 像素密度(dpi) = / 6.67
2. 像素密度(dpi) = 6926400 / 6.67
3. 394.573532825 = 6926400 / 6.67
「即:每寸越有395个像素」
三、常用单位
3.1 密度无关像素(dp)
density-independent pixel,叫dp或dip,与终端上的实际物理像素点无关。可以保证在不同屏幕像素密度的设备上显示相同的效果
Android开发时用dp而不是px单位设置图片大小,是Android特有的单位场景:假如同样都是画一条长度是屏幕一半的线,如果使用px作为计量单位,那么在480x800分辨率手机上设置应为240px;在320x480的手机上应设置为160px,二者设置就不同了;如果使用dp为单位,在这两种分辨率下,160dp都显示为屏幕一半的长度。
3.2 独立比例像素(sp)
sp,即scale-independent pixels,与dp类似,但是可以根据文字大小首选项进行放缩,是设置字体大小的御用单位。
3.3 dp与px的转换
在Android中,规定以160dpi(即屏幕分辨率为320x480)为基准:1dp=1px。
px = dp * (dpi / 160)
密度类型 | 代表的分辨率(px) | 屏幕密度(dpi) | 换算(px/dp) | 比例 |
---|---|---|---|---|
低密度(ldpi) | 240x320 | 120 | 1dp=0.75px | 3 |
中密度(mdpi) | 320x480 | 160 | 1dp=1px | 4 |
高密度(hdpi) | 480x800 | 240 | 1dp=1.5px | 6 |
超高密度(xhdpi) | 720x1280 | 320 | 1dp=2px | 8 |
超超高密度(xxhdpi) | 1080x1920 | 480 | 1dp=3px | 12 |
四、解决方案
4.1 今日头条
px值 = dp值 * metrics.density
,这里的density
是指的手机的屏幕密度,由系统提供,不同的手机的density
可能不同;所以我们不能直接使用系统的density
,需要篡改density
来达到适配的目的
public class MainActivity extends AppCompatActivity {
private static float sNoncompatDensity;// 系统的Density
private static float sNoncompatScaleDensity;// 系统的ScaledDensity
private static void setCustomDensity(Activity activity, final Application application){
final DisplayMetrics appDisplayMetrics = application.getResources().getDisplayMetrics();
if(sNoncompatDensity == 0){
// 系统的Density
sNoncompatDensity = appDisplayMetrics.density;
// 系统的ScaledDensity
sNoncompatScaleDensity = appDisplayMetrics.scaledDensity;
// 监听在系统设置中切换字体
application.registerComponentCallbacks(new ComponentCallbacks() {
@Override
public void onConfigurationChanged(@NonNull Configuration newConfig) {
if(newConfig != null && newConfig.fontScale > 0){
sNoncompatScaleDensity = application.getResources().getDisplayMetrics().scaledDensity;
}
}
@Override
public void onLowMemory() {
}
});
}
// 此处以360dp的设计图作为例子
final float targetDensity = appDisplayMetrics.widthPixels / 360;
final float targetScaledDensity = targetDensity * (sNoncompatScaleDensity/sNoncompatDensity);
final int targetDensityDpi = (int)(160 * targetDensity);
appDisplayMetrics.density = targetDensity;
appDisplayMetrics.scaledDensity = targetScaledDensity;
appDisplayMetrics.densityDpi = targetDensityDpi;
final DisplayMetrics activityDisplayMetrics = activity.getResources().getDisplayMetrics();
activityDisplayMetrics.density = targetDensity;
activityDisplayMetrics.scaledDensity = targetScaledDensity;
activityDisplayMetrics.densityDpi = targetDensityDpi;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setCustomDensity(this,this.getApplication());
setContentView(R.layout.activity_main);
}
}
4.2 ScreenMatch适配
Android ScreenMatch屏幕适配是一种简单适用的适配方式,是由Android官方推出的适配方法
4.2.1 下载插件
4.2.2 使用
之后会有选择项目的界面,选择你想在哪个项目中使用ScreenMatch。
根据你选择的尺寸来生成对应的values,默认有一大堆。
4.2.3 自定义values文件
在screenMatch.properties中你需要关注:
-
1.base_dp:若base_dp=360这种机型在你项目中就不可能有,你完全可以根据你项目中的基础机型来配置这个基础base_dp。我这是UI用的375,所以此处改为375。
-
2.match_dp和ignore_dp要配合使用:
-
match_dp:需要的尺寸
-
ignore_dp:忽略的尺寸
-
所有尺寸在红框上方的注解里面有。
4.3 选择适配方案->今日头条
-
1.快捷方便
-
2.后期维护调整也省事
-
3.包体小