简述

一个App可能会要运行于不同屏幕尺寸的Android设备上,因此多屏幕设计就是为解决这个需求。

支持不同的屏幕尺寸

即屏幕适配,需要根据不同的屏幕尺寸,调整UI为最合适的体验效果,而一些图片的显示,也不能发生变形。

使用”wrap_content” 和”match_parent”

对于一些view组件,使用这两个属性,可以使view组件的长和宽适配不同的屏幕尺寸,如果使用hard-coded方式来确定view组件的尺寸,在搬移到不同的屏幕尺寸的设备时必会出现UI问题。
wrap_content,即是将内容进行包裹,仅使用最小的长度和宽度来容纳这个view组件的内容,是紧凑型布置。
match_parent则是最大限度拉大长度和宽度,来填充它的父组件的空间。

使用RelativeLayout

常用的LinearLayout并不能精确控制和子视图的关系,而是只能依次一个挨着一个摆放。RelativeLayout使得可以控制子视图的相对位置,如在上一个子视图的上/下/左/右等等。

使用尺寸限定

即对于可能的不同屏幕尺寸设备,使用两份layout,一份为large,一份为普通,large的部分可以多放一个Fragment,而普通的只放一个Fragment。

使用Smallest-width限定

如上面的尺寸限定所述,只是很笼统的一个大小的划分,而有的设备,比如5寸屏幕和7寸屏幕,都可以属于large,但是如何需要区别两者的话,就可以用Smallest-width限定,如7寸屏幕最小宽度为600dp,layout-sw600dp/xxx.xml就表示需要最小宽度为600dp的屏幕使用,而小于的则使用layout/xxx.xml了。

使用layout别名

一般会使用不同文件夹命名来区分适应不同屏幕的layout:
res/layout: single-pane layout
res/layout-large: multi-pane layout
res/layout-sw600dp: multi-pane layout
如果使用别名,可以在一般的尺寸的layout中定义两个layout,然后分别加到large和sw600dp中:
res/layout/main.xml, single-pane layout
res/layout/main_twopanes.xml, two-pane layout
加到values-large中:
res/values-large/layout.xml:

<resources>
<item name="main" type="layout">@layout/main_twopanes</item>
</resources>

加到values-sw600dp中:
res/values-sw600dp/layout.xml:

<resources>
<item name="main" type="layout">@layout/main_twopanes</item>
</resources>

这样,后面两个.xml文件中虽然没有定义layout,但是通过别名的方式,设置了main_twopanes.xml的layout。

使用方向限定

主要是针对横屏还是竖屏进行布局的限定。

支持不同的屏幕分辨率

使用分辨率无关的Pixel(像素)

在设计UI时最好不用用绝对像素来定义尺寸和距离,这主要涉及两种单位的使用: dp和sp。dp一般用于尺寸表示,sp一般用来限定文字大小。

提供可选位图

在工程的lancher logo就可以看到,对于不同尺寸的设备,需要提供多份位图源文件。如下是比例:
xhdpi: 2.0
hdpi: 1.5
mdpi: 1.0 (baseline)
ldpi: 0.75

实现UI适配的流程

活动中定义当前的layout

public class NewsReaderActivity extends FragmentActivity
boolean mIsDualPane;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_layout);

View articleView = findViewById(R.id.article);
mIsDualPane = articleView != null