在看到本文之前,如果读者没看过笔者的前文Android屏幕适配知识 ,请先翻阅。
支持各种屏幕尺寸:
使用wrap_content,match_parent,weight
使用相对布局,禁用绝对布局
使用限定符
使用自动拉伸位图
一、weight详解
以下布局,Button1所占位置:Button2所占位置=1:2
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Button1" />
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2"
android:text="Button2" />
</LinearLayout>
但如果把上述两个Button的layout_width设置为"match_parent",则
Button1所占位置:Button2所占位置=2:1
我们来分析一下weight
其计算出来的宽度=控件宽度+剩余空间所占百分比的宽度
设屏幕宽度为L
以Button1为例,其宽度为"match_parent",即宽度为L
同理Button2的宽度也为L
则Button1实际显示宽度= L + (L-2L)*1/3=2/3L
其中剩余空间=屏幕宽度-Button1宽度-Button2宽度
所以Button1所占位置:Button2所占位置=2:1
二、限定符详解
使用限定符:
使用尺寸限定符
使用最小宽度限定符
使用布局别名
使用屏幕方向限定符
1、尺寸限定符
可用尺寸限定符layout-large让系统在屏幕尺寸大于7英寸时采用适配平板的布局,反之采用适配手机的布局,两个布局名称均为main.xml,只有尺寸限定符不一样。
适配手机:
res/layout/main.xml
适配平板:
res/layout-large/main.xml
但要注意的是,这种方式只适合Android 3.2版本之前。
2、最小宽度限定符
在Android 3.2及之后版本,可采用最小宽度限定符,以精确判断适配尺寸
适配手机:
res/layout/main.xml
适配平板:
res/layout-sw600dp/main.xml
sw即small width的缩写,其不区分方向,即无论是宽度还是高度,只要大于600dp,就采用这个布局。
但这会带来一个问题,在Android 3.2版本之前,需要同时维护layout-sw600dp和layout-large的两套main.xml平板布局
3、布局别名
为了解决以上问题,可采用布局别名技术
手机布局:res/layout/main.xml
平板布局:res/layout/main_twopanes.xml
默认手机布局:
res/values/layout.xml:
<resources>
<item name="main" type="layout">@layout/main</item>
</resources>
Android 3.2之前的平板布局:
res/values-large/layout.xml:
<resources>
<item name="main" type="layout">@layout/main_twopanes</item>
</resources>
Android 3.2及之后的平板布局:
res/values-sw600dp/layout.xml:
<resources>
<item name="main" type="layout">@layout/main_twopanes</item>
</resources>
这样,就只需要维护一套平板布局main_twopanes.xml
值得注意的是,此时设置布局文件应用resources中的item名字setContentView(R.layout.main)
4、屏幕方向限定符
适用场景:平板纵向和横向布局不一致
横向布局:res/layout-sw600dp-land/main.xml
纵向布局:res/layout-sw600dp-port/main.xml
可为resources设置bool,通过获取其值来动态判断目前已处在哪个适配布局
res/values-sw600dp/layout.xml:
<resources>
<item name="main" type="layout">@layout/main_twopanes</item>
<bool name="has_two_panes">true</bool>
</resources>