Android屏幕适配及DisplayMetrics解析

一、基本概念
1、屏幕尺寸
屏幕尺寸指屏幕的对角线的长度,单位是英寸(in),1英寸=2.54厘米

2、px
是英文单词pixel的缩写,意为像素,屏幕上的点。我们通常所说的分辨率如480X800就是指的像素,一般以纵向像素*横向像素。

3、dpi
dpi是Dots Per Inch的缩写, 每英寸点数,即每英寸包含像素个数。

dpi的计算方法:

4、density
屏幕密度,density和dpi的关系为 density = dpi/160

4、dp和dip
设备独立像素,device independent pixels的缩写,Android特有的单位,在屏幕密度dpi = 160屏幕上,1dp = 1px。dp和density的关系为 1dp = density px,dip值 =(dpi值/160)* pixel值

5、sp
和dp很类似,一般用来设置字体大小,和dp的区别是它可以根据用户的字体大小偏好来缩放。

问题:
1、为什么我们需要推荐使用dp而不推荐使用px
不使用px的原因是由于不同的手机分辨率是不同的,相同的像素对应的尺寸是不同的。

推荐使用dp的原因是我们可以通过dp设置指定的尺寸,这个不受像素的影响,是像素无关的。从上面可以看出dp就是等于屏幕密度,从而可以得到1dp对应设备的像素,这样我们就可以设置真实的尺寸大小,这个大小跟像素是无关的。就是说dp能够让同一数值在不同的分辨率展示出大致相同的尺寸大小。

2、为什么dp还是不能解决屏幕适配的问题
dp可以用来设置指定尺寸,这个不受像素的影响,这样对不同的手机我们可以指定相同的尺寸,但还有一个问题就是市面上的手机尺寸并不是相同的,常见的屏幕尺寸有2.4、2.8、3.5、3.7、4.2、5.0、5.5、6.0等,对于这么多尺寸,我们在为布局设置宽高的时候,的确可以使用dp来给定一个固定的大小,但是我们却不知道用户手机的尺寸是多少,如果设置尺寸太大,可能屏幕容纳不小,如果设置的尺寸太小,屏幕可能留出许多的空白区域。

二、Android Drawable适配
1、普通drawable
新建一个Android项目后应该可以看到很多drawable文件夹,分别对应不同的dpi

drawable-ldpi (dpi=120, density=0.75)

drawable-mdpi (dpi=160, density=1)

drawable-hdpi (dpi=240, density=1.5)

drawable-xhdpi (dpi=320, density=2)

drawable-xxhdpi (dpi=480, density=3)

对于五种主流的像素密度(MDPI、HDPI、XHDPI、XXHDPI 和 XXXHDPI)应按照 2:3:4:6:8 的比例进行缩放。

我们一般的做法是以高分辨率作为设计大小,然后按照倍数对应缩小到小分辨率的图片。因为小分辨率在生成高分辨率图片的时候,会出现像素丢失。

2、自动拉伸位图

如果在可以更改尺寸的组件上使用了简单的图片,您很快就会发现显示效果多少有些不太理想,因为系统会在运行时平均地拉伸或收缩您的图片。解决方法为使用自动拉伸位图,这是一种格式特殊的 PNG 文件,其中会指明可以拉伸以及不可以拉伸的区域,这个就是NinePatch图片。

.9的制作,实际上就是在原图片上添加1px的边界,然后按照我们的需求,把对应的位置设置成黑色线,系统就会根据我们的实际需求进行拉伸。

三、布局的适配
对于不同的屏幕,如果差别太大,我们就需要使用不同的布局文件,我们可以通过使用配置限定符,在运行时根据当前的设备配置自动选择合适的资源了,例如根据各种屏幕尺寸选择不同的布局。
根据物理尺寸的大小准备5套布局:
layout(放一些通用布局xml文件,比如界面顶部和底部的布局,不会随着屏幕大小变化,类似windos窗口的title bar)

layout-small(屏幕尺寸小于3英寸左右的布局)

layout-normal(屏幕尺寸小于4.5英寸左右)

layout-large(4英寸-7英寸之间)

layout-xlarge(7-10英寸之间)

四、百分比布局
这是最理想的一种布局方案,使用百分比就可以完全不用担心适配的问题。android-percent-support这个库
用法可以看下面博客:Android 百分比布局库(percent-support-lib) 解析与扩展Android 增强版百分比布局库 为了适配而扩展
.
另外,还有另外一种方案,根据一个基准,比如480*320的分辨率为基准,对各种不同手机的像素按照这个标准将垂直像素和水平像素分别均分成480份和320份。这样就可以得到每一份的像素,我们在设置的时候,直接使用份数就可以了,这也相当于是百分比,具体参照下面文章:Android 屏幕适配方案

五、注意点
1、使用wrap_content、match_parent、weight

weight的计算方法:设置宽度(android:layout_width) + 剩余宽度的占位比

2、使用相对布局,禁用绝对布局

3、使用限定符

4、使用自动拉伸位图

六、DisplayMetrics解析
有了上面的概念和知识,下面我们可以可来讲讲DisplayMetrics了。

1、获取屏幕分辨率信息的三种方法:

DisplayMetrics metrics = new DisplayMetrics();
Display display = activity.getWindowManager().getDefaultDisplay();
display.getMetrics(metrics);

DisplayMetrics metrics=activity.getResources().getDisplayMetrics(); 

Resources.getSystem().getDisplayMetrics();

2、上面所有的单位到px的转换

android.util.TypedValue类提供了一个函数,支持把所有的单位换算到px,实现代码如下:

public static float applyDimension(int unit, float value,  
                                   DisplayMetrics metrics)  
{  
    switch (unit) { 
    //px:pixel 
    case COMPLEX_UNIT_PX:  
        return value;  
    //dp(dip)
    case COMPLEX_UNIT_DIP:  
        return value * metrics.density; 
    //sp  
    case COMPLEX_UNIT_SP:  
        return value * metrics.scaledDensity;  
    //pt : 1/72英寸
    case COMPLEX_UNIT_PT:  
        return value * metrics.xdpi * (1.0f/72); 
    //in: inch 英寸 
    case COMPLEX_UNIT_IN:  
        return value * metrics.xdpi;  
    //mm : 毫米  1英寸=25.4毫米
    case COMPLEX_UNIT_MM:  
        return value * metrics.xdpi * (1.0f/25.4f);  
    }  
    return 0;  
} 

从上面我们可以看到dp、sp、pt、in、mm转换为px的方法。

在上面用到了DisplayMetrics对象,在这个对象中有哪些内容,我们来看看这个类。

//设备的绝对宽度,单位是px
public int widthPixels;

//设备的绝对高度,单位是px
public int heightPixels;

//屏幕密度,它的计算方法在上面的概念中已经给出了
public float density;

//dpi 上面的概念已经给出,单位尺寸的像素点
public int densityDpi;

//字体显示的缩放因子,跟上面的density是一样
public float scaledDensity;

//水平方向的dpi
public float xdpi;

//竖直方向的dpi
public float ydpi;

3、运用

在TextView里面有个setTextSize方法,它可以指定设置字体的单位。

mTestText1 = (TextView) findViewById(R.id.test1);
mTestText1.setTextSize(TypeValue.COMPLEX_UNIT_SP, 18);

上面就是将TextView对象的字体设置为18sp.

我们来看看它内部的实现源码。

public void setTextSize(float size) {
        setTextSize(TypedValue.COMPLEX_UNIT_SP, size);
}

public void setTextSize(int unit, float size) {
    Context c = getContext();
    Resources r;

    if (c == null)
        r = Resources.getSystem();
    else
        r = c.getResources();

    setRawTextSize(TypedValue.applyDimension(
        unit, size, r.getDisplayMetrics()));
}

从上面可以看到,它默认单位就是TypedValue.COMPLEX_UNIT_SP,最终调用的其实就是上面我们讲到的TypedValue.applyDimension方法,其实它就是把sp转成了px.

相关文章:
Android屏幕适配全攻略(最权威的官方适配指导)

Android 屏幕适配

android屏幕适配详解

官方链接:

Supporting Multiple Screens

http://screensiz.es/phone

  • 10
    点赞
  • 42
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值