Android屏幕适配总结
一、细说layout_weight
目前最为推荐的Android多屏幕自适应解决方案。
该属性的作用是决定控件在其父布局中的显示权重,一般用于线性布局中。其值越小,则对应的layout_width或layout_height的优先级就越高,一般横向布局中,决定的是layout_width的优先级;纵向布局中,决定的是layout_height的优先级。
传统的layout_weight使用方法是将当前控件的layout_width和layout_height都设置成fill_parent,这样就可以把控件的显示比例完全交给layout_weight;这样使用的话,就出现了layout_weight越小,显示比例越大的情况。不过对于2个控件还好,如果控件过多,且显示比例也不相同的时候,控制起来就比较麻烦了,毕竟反比不是那么好确定的。
于是就有了现在最为流行的layout_width=0dp或者layout_height=0dp结合layout_weight=设值法,可以使控件成正比例显示。看似让人难以理解的layout_height=0dp的写法,结合layout_weight,却可以使控件成正比例显示,轻松解决了当前Android开发最为头疼的碎片化问题之一。
先看下面的styles(style_layout.xml)
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
<?xml version= "1.0" encoding= "utf-8" ?> <resources> <!-- 全屏幕拉伸--> <style name= "layout_full" > <item name= "android:layout_width" >fill_parent</item> <item name= "android:layout_height" >fill_parent</item> </style> <!-- 固定自身大小--> <style name= "layout_wrap" > <item name= "android:layout_width" >wrap_content</item> <item name= "android:layout_height" >wrap_content</item> </style> <!-- 横向分布--> <style name= "layout_horizontal" parent= "layout_full" > <item name= "android:layout_width" >0px</item> </style> <!-- 纵向分布--> <style name= "layout_vertical" parent= "layout_full" > <item name= "android:layout_height" >0px</item> </style> </resources> |
可以看到,layout_width和layout_height两个属性被我封装成了4个style
根据实际布局情况,选用当中的一种,不需要自己设置,看过我前一个ActivityGroup的Demo的同学应该非常熟悉了
然后我的Demo的布局如下(weight_layout.xml)
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
|
<?xml version= "1.0" encoding= "utf-8" ?> <LinearLayout xmlns:android= "http://schemas.android.com/apk/res/android" style= "@style/layout_full" android:orientation= "vertical" > <LinearLayout style= "@style/layout_vertical" android:layout_weight= "1" android:orientation= "horizontal" > <View style= "@style/layout_horizontal" android:background= "#aa0000" android:layout_weight= "1" /> <View style= "@style/layout_horizontal" android:background= "#00aa00" android:layout_weight= "4" /> <View style= "@style/layout_horizontal" android:background= "#0000aa" android:layout_weight= "3" /> <View style= "@style/layout_horizontal" android:background= "#aaaaaa" android:layout_weight= "2" /> </LinearLayout> <LinearLayout style= "@style/layout_vertical" android:layout_weight= "2" android:orientation= "vertical" > <View style= "@style/layout_vertical" android:background= "#ffffff" android:layout_weight= "4" /> <View style= "@style/layout_vertical" android:background= "#aa0000" android:layout_weight= "3" /> <View style= "@style/layout_vertical" android:background= "#00aa00" android:layout_weight= "2" /> <View style= "@style/layout_vertical" android:background= "#0000aa" android:layout_weight= "1" /> </LinearLayout> </LinearLayout> |
整个界面布局看起来非常直观,只是嵌套的逻辑要自己理下。显示效果如下图,其中左面一个是480x800的界面,右面的是320x480的界面(后面的图也如此),可以看出显示比例和代码中完全一致,我就不多说了,大家对照下就能看出来了。
![](http://www.eoeandroid.com/data/attachment/forum/201205/22/1432178gcsrre8adr88rcg.png)
![](http://www.eoeandroid.com/data/attachment/forum/201205/22/143613r1t4lmmoczrmrflr.png)
四、多布局
做为最后的方法,也是最后一个才会考虑的方法,那就是为不同的尺寸界面单独写布局。不到万不得已不要用这个方法,相信不少人和我一样都被逼着用过这个方法吧。需要说明的是,横竖屏切换使用不同布局也是用这个方法解决的;代码我就不上了,给大家看两张图吧,一个是同1个布局的,一个是写了多布局的,大家一看就明白了
补充一下,写多个布局的时候,配置文件一定要加上这段配置代码,不然有时可能会出问题<supports-screens android:largeScreens="true"
android:normalScreens="true" android:anyDensity="true" />
![](http://www.eoeandroid.com/data/attachment/forum/201205/22/14381743zwza4z1z002e23.png)
![](http://www.eoeandroid.com/data/attachment/forum/201205/22/143827r8ir7rx8rxa0f0i3.png)
五、其他
以上说的都是多个屏幕显示相同内容需要考虑的问题,还有一种是在不同的屏幕上显示内容不同的情况,其实这个问题我们往往是用滚动视图来解决的,也就是ScrowView;需要注意的是ScrowView中使用layout_weight是无效的,既然使用ScrowView了,就把它里面的控件的大小都设成固定的吧。
此外关于图片的自适应问题,主要是2点,一个是9patch图,这个东西大家都要学会去做,不难;不过有些编译器在识别9patch图时会出这样那样的bug,像我的Eclipse就不认这个,而同一个9patch图在别的电脑上却是没问题的,
第二个要说的是我曾经被困扰的一个问题,对于480x800 和 480x854这两个尺寸,他们显示同一个图片时,总有一个会拉伸(如果9patch可以解决的还好)。其实当初困扰我的是,这两个尺寸都是hdpi的,以为无法给这两个屏幕做不同的图片。后来无意中发现,图片可以和布局一样分多个尺寸的,而不仅仅是根据密度分,也就是说你可以写这样的文件夹drawable-hdpi-800x480和drawable-hdpi-854x480,在它们里面放不同的图片,这样图片也能自适应了