Android屏幕适配

屏幕尺寸

屏幕尺寸指屏幕的对角线的长度,单位是英寸,1英寸=2.54厘米

比如常见的屏幕尺寸有2.4、2.8、3.5、3.7、4.2、5.0、5.5、6.0等


屏幕分辨率

屏幕分辨率是指在横纵向上的像素点数,单位是px,1px=1个像素点。一般以纵向像素*横向像素,如1960*1080。


屏幕像素密度

屏幕像素密度是指每英寸上的像素点数,单位是dpi,即“dot per inch”的缩写。屏幕像素密度与屏幕尺寸和屏幕分辨率有关,在单一变化条件下,屏幕尺寸越小、分辨率越高,像素密度越大,反之越小。



dp、dip、dpi、sp、px

px我们应该是比较熟悉的,前面的分辨率就是用的像素为单位,大多数情况下,比如UI设计、 Android原生API都会以px作为统一的计量单位,像是获取屏幕宽高等

dip和dp是一个意思,都是Density Independent Pixels的缩写,即密度无关像素,上面我们说过,dpi是屏幕像素密度,假如一英寸里面有160个像素,这个屏幕的像素密度就是160dpi,那么在这种情况下,dp和px如何换算呢?在Android中,规定以160dpi为基准,1dip=1px,如果密度是320dpi,则1dip=2px,以此类推。

而sp,即scale-independent pixels,与dp类似,但是可以根据文字大小首选项进行放缩,是设置字体大小的御用单位。


Android屏幕适配_第1张图片


设计图标的规格:
Android屏幕适配_第2张图片

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

例如,一个启动图标的尺寸为48x48 dp,这表示在 MDPI 的屏幕上其实际尺寸应为 48x48 px,在 HDPI 的屏幕上其实际大小是 MDPI 的 1.5 倍 (72x72 px),在 XDPI 的屏幕上其实际大小是 MDPI 的 2 倍 (96x96 px),依此类推。

解决方案:

支持各种屏幕尺寸

1 :使用wrap_content、match_parent、weight

eg:
Android屏幕适配_第3张图片

--- 下图是在横纵屏切换的时候的显示效果,我们可以看到这样可以很好的适配屏幕尺寸的变化。

Android屏幕适配_第4张图片


weight:
Android屏幕适配_第5张图片

真正用的时候,我们都是设置某一个属性为0dp,然后按照权重计算所占百分比。


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

由于各种布局的特点不一样,所以不能说哪个布局好用,到底应该使用什么布局只能根据实际需求来确定。我们可以使用 LinearLayout 的嵌套实例并结合 “wrap_content” 和 “match_parent”,以便构建相当复杂的布局。不过,我们无法通过 LinearLayout 精确控制子视图的特殊关系;系统会将 LinearLayout 中的视图直接并排列出。

如果我们需要将子视图排列出各种效果而不是一条直线,通常更合适的解决方法是使用 RelativeLayout,这样就可以根据各组件之间的特殊关系指定布局了。例如,我们可以将某个子视图对齐到屏幕左侧,同时将另一个视图对齐到屏幕右侧。


下面的代码以官方Demo为例说明。

Android屏幕适配_第6张图片

在上面的代码中我们使用了相对布局,并且使用alignXXX等属性指定了子控件的位置,下面是这种布局方式在应对屏幕变化时的表现.

在小尺寸屏幕的显示:

Android屏幕适配_第7张图片

在平板的大尺寸上的显示效果:

Android屏幕适配_第8张图片

虽然控件的大小由于屏幕尺寸的增加而发生了改变,但是我们可以看到,由于使用了相对布局,所以控件之前的位置关系并没有发生什么变化,这说明我们的适配成功了。

3: 使用尺寸限定符

我们可以通过使用配置限定符,在运行时根据当前的设备配置自动选择合适的资源了,例如根据各种屏幕尺寸选择不同的布局。

res/layout/main.xml,单面板(默认)布局:

Android屏幕适配_第9张图片


res/ layout-large /main.xml,双面板布局:

Android屏幕适配_第10张图片

请注意第二种布局名称目录中的 large 限定符。系统会在属于较大屏幕(例如 7 英寸或更大的平板电脑)的设备上选择此布局。系统会在较小的屏幕上选择其他布局(无限定符)。

4:使用最小宽度限定符

res/layout/main.xml,单面板(默认)布局:

Android屏幕适配_第11张图片

res/ layout-sw600dp /main.xml,双面板布局:

[layout-sw600dp:小宽度大于等于 600 dp 的设备,系统会选择 layout-sw600dp/main.xml(双面板)布局,否则系统就会选择 layout/main.xml(单面板)布局。]

[但 Android 版本低于 3.2 的设备不支持此技术,原因是这些设备无法将 sw600dp 识别为尺寸限定符,因此我们仍需使用 large 限定符。]
Android屏幕适配_第12张图片

5: 使用布局别名 [解决Andrioid版本3.2的设备使用最小宽度限定符的布局适配问题]

首先提供2个布局
  • res/layout/main.xml,单面板布局

  • res/layout/main_twopanes.xml,双面板布局


然后添加这两个文件:

res/values-large/layout.xml: 【3.2版本一下】


res/values-sw600dp/layout.xml: 【3.2版本以上】


6:使用屏幕方向限定符 【配合布局别名技术使用】

某些布局会同时支持横向模式和纵向模式,但我们可以通过调整优化其中大部分布局的效果
比如:

小屏幕,纵向:单面板,带徽标
小屏幕,横向:单面板,带徽标
7 英寸平板电脑,纵向:单面板,带操作栏
7 英寸平板电脑,横向:双面板,宽,带操作栏
10 英寸平板电脑,纵向:双面板,窄,带操作栏
10 英寸平板电脑,横向:双面板,宽,带操作栏
电视,横向:双面板,宽,带操作栏

因此,这些布局中的每一种都定义在了 res/layout/ 目录下的某个 XML 文件中。为了继续将每个布局分配给各种屏幕配置,该应用会使用布局别名将两者相匹配:

res/layout/onepane.xml:(单面板)
Android屏幕适配_第13张图片

res/layout/onepane_with_bar.xml:(单面板带操作栏)
Android屏幕适配_第14张图片

res/layout/twopanes.xml:(双面板,宽布局)

Android屏幕适配_第15张图片


res/layout/twopanes_narrow.xml:(双面板,窄布局)

Android屏幕适配_第16张图片

既然我们已定义了所有可能的布局,那就只需使用配置限定符将正确的布局映射到各种配置即可。

现在只需使用布局别名技术即可做到这一点:


res/ values/layouts.xml :

res/ values-sw600dp-land/layouts.xml:


res/ values-sw600dp-port/layouts.xml:


res/ values-large-land/layouts.xml:


res/ values-large-port/layouts.xml:


7:使用9patch图片

8:使用dp指定两个视图间的间距,使用sp指定文字大小

假如我们以Nexus5作为书写代码时查看效果的测试机型,Nexus5的总宽度为360dp,我们现在需要在水平方向上放置两个按钮,一个是150dp左对齐,另外一个是200dp右对齐,中间留有10dp间隔,那么在Nexus5上面的显示效果就是下面这样

Android屏幕适配_第17张图片

但是如果在Nexus S或者是Nexus One运行呢?下面是运行结果

Android屏幕适配_第18张图片


Nexus S和Nexus One属于hdpi,屏幕宽度是320dp,而Nexus 5属于xxhdpi,屏幕宽度是360dp,Galaxy Nexus属于xhdpi,屏幕宽度是384dp,Nexus 6 属于xxxhdpi,屏幕宽度是410dp。

所以说,光Google自己一家的产品就已经有这么多的标准,而且屏幕宽度和像素密度没有任何关联关系,即使我们使用dp,在320dp宽度的设备和410dp的设备上,还是会有90dp的差别。

当然,我们尽量使用match_parent和wrap_content,尽可能少的用dp来指定控件的具体长宽,再结合上权重,大部分的情况我们都是可以做到适配的。 【最重点常用】

9:提供备用位图

由于 Android 可在具有各种屏幕密度的设备上运行,因此我们提供的位图资源应始终可以满足各类普遍密度范围的要求:低密度、中等密度、高密度以及超高密度。这将有助于我们的图片在所有屏幕密度上都能得到出色的质量和效果。

要生成这些图片,我们应先提取矢量格式的原始资源,然后根据以下尺寸范围针对各密度生成相应的图片。

  • xhdpi:2.0

  • hdpi:1.5

  • mdpi:1.0(最低要求)

  • ldpi:0.75

也就是说,如果我们为 xhdpi 设备生成了 200x200 px尺寸的图片,就应该使用同一资源为 hdpi、mdpi 和 ldpi 设备分别生成 150x150、100x100 和 75x75 尺寸的图片。

然后,将生成的图片文件放在 res/ 下的相应子目录中(mdpi、hdpi、xhdpi、xxhdpi),系统就会根据运行您应用的设备的屏幕密度自动选择合适的图片。

这样一来,只要我们引用 @drawable/id,系统都能根据相应屏幕的 dpi 选取合适的位图。

还记得我们上面提到的图标设计尺寸吗?和这个其实是一个意思。

如果是.9图或者是不需要多个分辨率的图片,就放在drawable文件夹即可,对应分辨率的图片要正确的放在合适的文件夹,否则会造成图片拉伸等问题。


............................................................中间参考...............................................................................................
http://www.cocoachina.com/android/20151030/13971.html--- Android屏幕适配全攻略(最权威的官方适配指导)

http://blog.csdn.net/lmj623565791/article/details/45460089----鸿洋

http://blog.csdn.net/lmj623565791/article/details/46695347---百分比布局库

最佳实践

关于高清设计图尺寸

Google官方给出的高清设计图尺寸有两种方案,一种是以mdpi设计,然后对应放大得到更高分辨率的图片,另外一种则是以高分辨率作为设计大小,然后按照倍数对应缩小到小分辨率的图片。

根据经验,我更推荐第二种方法,因为小分辨率在生成高分辨率图片的时候,会出现像素丢失,我不知道是不是有方法可以阻止这种情况发生。

而分辨率可以以1280*720或者是1960*1080作为主要分辨率进行设计。

ImageView的ScaleType属性

设置不同的ScaleType会得到不同的显示效果,一般情况下,设置为centerCrop能获得较好的适配效果。

动态设置

有一些情况下,我们需要动态的设置控件大小或者是位置,比如说popwindow的显示位置和偏移量等,这个时候我们可以动态的获取当前的屏幕属性,然后设置合适的数值

1
2
3
4
5
6
7
8
9
10
11
public class ScreenSizeUtil {
public static int getScreenWidth(Activity activity) {
return  activity.getWindowManager().getDefaultDisplay().getWidth();
}
public static int getScreenHeight(Activity activity) {
return  activity.getWindowManager().getDefaultDisplay().getHeight();
}
}

你可能感兴趣的:(Android基础)