在画页面时,常常会出现一个烦恼,页面在不同屏幕大小的手机上 变形了,要么被拉升要么挤到了一块,要么字的大小超出了btn范围。即使采用了所谓的自适应屏幕的dp、sp单位、但仍然无法完美的适配多个屏幕。
下面就来谈谈如何做到屏幕适配
1.ViewGroup类(LinearLayout、RelativeLayout等)善用layout_weight、动态设置宽高
2.ImageView类,9Patch图、 IconFont(IconMoon)
一、善用layout_weight
<?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>
<?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的界面(后面的图也如此),可以看出显示比例和代码中完全一致,我就不多说了,大家对照下就能看出来了。
在复杂的界面构造中,仅仅靠layout_weight不能解决我们的问题,这时我们可以动态设置组件的宽高
public class Constant { public static int displayWidth; //屏幕宽度 public static int displayHeight; //屏幕高度 }
然后在第一个Activity启动的时候,获取这两个值
DisplayMetrics displayMetrics = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(displayMetrics); Constant.displayWidth = displayMetrics.widthPixels; Constant.displayHeight = displayMetrics.heightPixels;
布局代码我们可以全都统一写成wrap-content,其实写成什么都无所谓,因为这个值只是暂时的
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <Button android:id="@+id/btn1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="#ffcccc" android:text="aaaaaaaa"/> <Button android:id="@+id/btn2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="#ccffcc" android:text="bbbbbbbbb"/> <Button android:id="@+id/btn3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="#ccccff" android:text="ccccccccc"/> <Button android:id="@+id/btn4" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="#ffffcc" android:text="dddddddddddddddddd"/> </LinearLayout>
最后我们在Activity的onCreate方法里这么做
// 第一个按钮,宽度100%,高度10% LinearLayout.LayoutParams params = new LinearLayout.LayoutParams( LayoutParams.FILL_PARENT, (int) (Constant.displayHeight * 0.1f + 0.5f)); btn1.setLayoutParams(params); // 第二个按钮,宽度100%,高度30% LinearLayout.LayoutParams params2 = new LinearLayout.LayoutParams( LayoutParams.FILL_PARENT, (int) (Constant.displayHeight * 0.3f + 0.5f)); btn2.setLayoutParams(params2); // 第三个按钮,宽度50%,高度20% LinearLayout.LayoutParams params3 = new LinearLayout.LayoutParams( (int) (Constant.displayWidth * 0.5f + 0.5f), (int) (Constant.displayHeight * 0.2f + 0.5f)); btn3.setLayoutParams(params3); // 第三个按钮,宽度70%,高度填满剩下的空间 LinearLayout.LayoutParams params4 = new LinearLayout.LayoutParams( (int) (Constant.displayWidth * 0.7f + 0.5f), LayoutParams.FILL_PARENT); btn4.setLayoutParams(params4);
三、9patch图的制作
关于9patch图,网上已有很多相关的资料介绍,在这里不作赘述,只作引荐,好处就是对于各种button的背景图再也不用根据不同屏幕大小做多张图了!
详见:
http://www.cnblogs.com/xiaoran1129/archive/2012/07/04/2576461.html
或 http://www.cnblogs.com/qianxudetianxia/archive/2011/04/17/2017591.html
四、IconFont、Icomoon
IconFont是阿里旗下的APP图标库,淘宝、支付宝、阿里旅行很多都用到了这种图标,官网为http://www.iconfont.cn/
Icomoon是国外的网站,与IconFont作用相同,读者选用一种即可,官网:https://icomoon.io/
IconFont 即图标字体,实质是一种字体,用TextView来加载,调用setText()即可。
其优点为:
1.减少图片资源,从而大大减少apk的大小。用IconFont打包出来的字体文件.ttf,一般都十几kb,这比制作两套尺寸的图片资源,从效率上 体积上都要强得多
2.由于图标字体都是矢量图,拉伸不会变形,开发者可以随意定义字体大小及颜色
缺点:图标只能定义纯色,不能有渐变等多种颜色效果
可以看到win8大量运用了这种图标(是的,IconFont不拘泥与平台,在web、ios中都可以使用)
IconFont的使用:
http://mux.alimama.com/posts/964