首页 > 代码库 > 关于Android屏幕适配的总结

关于Android屏幕适配的总结

Android用两种常规的属性来分类设备屏幕:即尺寸和像素密度。作为开发者,我们在设计应用的时候必须要考虑到我们所做的应用会被安装到不同屏幕尺寸和像素密度的设备上。因此,我们的应用应当包含可选的资源来优化应用外观,以便支持不同尺寸和像素密度的设备。

有四种广义上的尺寸:small、normal、large、xlarge。

同样也有四种广义的像素密度:low (ldpi), medium (mdpi), high (hdpi), extra high (xhdpi) 

为了声明用于不同屏幕的不同layouts布局和bitmaps资源,我们必须把这些可选的资源文件分别放在不同的目录,这一点类似于我们在国际化时不同语言strings的操作。 

同时要注意屏幕的方向(landscape or portrait)也被认为是一种屏幕尺寸的变化,所以我们的应用应该修改layout布局来提高用户在不同屏幕方向上的体验。

为了提高在不同设备屏幕上的用户体验,我们应当为每一种你想要支持的屏幕尺寸创建一个独有的XML布局文件。每一布局文件应当存放到恰当的资源目录下,该目录以屏幕尺寸-<screen_size>作为后缀。例如,一个用于大屏幕的布局文件应当放在res/layout-large/目录下面。

需要注意的是:Android会自动缩放你的布局以便适配屏幕。那么,用于不同屏幕的布局文件就不必过多考虑UI元素的绝对大小,相反应当关注于布局的结构,这将直接影响用户体验(比如重要view视图的大小或位置应当相对于同级view视图)。

目录中的布局文件名必须保持一致,但是它们的内容可以不同,以便提供优化的UI来支持相对应的屏幕尺寸

app中简单地获得layout布局文件的引用,Android系统将根据你的app应用所运行设备的屏幕尺寸从适当的layout目录加载布局文件。 

我们还应当为所有广义像素密度中的每一种都提供已经缩放好的适当的bitmap资源:低low, medium, high以及特高extra-high像素密度。这将使我们的应用在所有分辨率的设备上都获得优良的图形质量和呈现效果。 

为了生成这些图片资源,我们应当以矢量图的格式来制作原始图片资源,然后根据它们缩放尺寸生成每一种分辨率的图片:

  • 特高分辨率xhdpi: 2.0
  • 高分辨率hdpi: 1.5
  • 中分辨率mdpi: 1.0 (基准)
  • 低分辨率ldpi: 0.75

这意味着如果我们要为特高分辨率设备生成一张200x200的图片,那么你需要为高分辨率设备生成150x150,中分辨率设备生成100x100,低分辨率设备生成75x75的图片。 

然后把这些文件放置到恰当的资源目录中。以后我们在引用drawable里的图片的时候,系统将根据设备的分辨率自动选择适当的图片资源。

 

对于分辨率问题,官方给的解决办法是创建不同的layout文件夹,这就需要对每种分辨率的手机都要写一个布局文件,虽然看似解决了分辨率的问题,但是如果其中一处或多处有修改了,就要每个布局文件都要做出修改,这样就造成很大的麻烦。那么可以通过以下几种方式解决:

一)使用layout_weight

目前最为推荐的Android多屏幕自适应解决方案。

该属性的作用是决定控件在其父布局中的显示权重,一般用于线性布局中。其值越小,则对应的layout_width或layout_height的优先级就越高(一般到100作用就不太明显了);一般横向布局中,决定的是layout_width的优先级;纵向布局中,决定的是layout_height的优先级。

传统的layout_weight使用方法是将当前控件的layout_width和layout_height都设置成fill_parent,这样就可以把控件的显示比例完全交给layout_weight;这样使用的话,就出现了layout_weight越小,显示比例越大的情况(即权重越大,显示所占的效果越小)。不过对于2个控件还好,如果控件过多,且显示比例也不相同的时候,控制起来就比较麻烦了,毕竟反比不是那么好确定的。于是就有了现在最为流行的0px设值法。看似让人难以理解的layout_height=0px的写法,结合layout_weight,却可以使控件成正比例显示,轻松解决了当前Android开发最为头疼的碎片化问题之一。

二)清单文件配置:(不建议使用这种方式,需要对不同的界面写不同的布局)

需要在AndroidManifest.xml文件的<manifest>元素如下添加子元素

<supports-screensandroid:largeScreens="true"

android:normalScreens="true"

android:anyDensity="true"

android:smallScreens="true" 

android:xlargeScreens="true">

</supports-screens>

以上是为我们的屏幕设置多分辨率支持(更准确的说是适配大、中、小三种密度)。

Android:anyDensity="true",这一句对整个的屏幕都起着十分重要的作用,值为true,我们的应用程序当安装在不同密度的手机上时,程序会分别加载hdpi,mdpi,ldpi文件夹中的资源。相反,如果值设置为false,即使我们在hdpi,mdpi,ldpi,xdpi文件夹下拥有同一种资源,那么应用也不会自动地去相应文件夹下寻找资源。而是会在大密度和小密度手机上加载中密度mdpi文件中的资源。

有时候会根据需要在代码中动态地设置某个值,可以在代码中为这几种密度分别设置偏移量,但是这种方法最好不要使用,最好的方式是在xml文件中不同密度的手机进行分别设置。这里地图的偏移量可以在values-xpdi,values-hpdi,values-mdpi,values-ldpi四种文件夹中的dimens.xml文件进行设置。

 

在屏幕适配的时候,通常还会注意到几点:

首先尽量使用线性布局,相对布局,如果屏幕放不下了,可以使用ScrollView(可以上下拖动)

ScrowView使用时要注意:

在不同的屏幕上显示内容不同的情况,其实这个问题我们往往是用滚动视图来解决的,也就是ScrowView;需要注意的是ScrowView中使用layout_weight是无效的,既然使用ScrowView了,就把它里面的控件的大小都设成固定的。

另外,在指定宽高的时候,采用dip的单位,dp单位动态匹配

3、由于android代码中写的单位都是像素,所有需要通过工具类进行转化

4、尽量使用9-patch图,可以自动的依据图片上面显示的内容被拉伸和收缩。在编辑的时候,灰色区域是被拉伸的,上下两个点控制水平方向的拉伸,左右两点控制垂直方向的拉伸,9-patch图工具在adt-bundle-windows-x86\sdk\tools目录下的draw9patch.bat

关于Android屏幕适配的总结