新手守则——关于Android屏幕适配

来源:互联网 发布:linux系统查看系统时间 编辑:程序博客网 时间:2024/06/05 16:29

在画页面时,常常会出现一个烦恼,页面在不同屏幕大小的手机上  变形了,要么被拉升要么挤到了一块,要么字的大小超出了btn范围。即使采用了所谓的自适应屏幕的dp、sp单位、但仍然无法完美的适配多个屏幕。


下面就来谈谈如何做到屏幕适配

1.ViewGroup类(LinearLayout、RelativeLayout等)善用layout_weight、动态设置宽高

2.ImageView类,9Patch图、 IconFont(IconMoon)


一、善用layout_weight

目前最为推荐的Android多屏幕自适应解决方案。
    该属性的作用是决定控件在其父布局中的显示权重,一般用于线性布局中。其值越小,则对应的layout_width或layout_height的优先级就越高,一般横向布局中,决定的是layout_width的优先级;纵向布局中,决定的是layout_height的优先级。
    传统的layout_weight使用方法是将当前控件的layout_widthlayout_height都设置成fill_parent,这样就可以把控件的显示比例完全交给layout_weight;这样使用的话,就出现了layout_weight越小,显示比例越大的情况。不过对于2个控件还好,如果控件过多,且显示比例也不相同的时候,控制起来就比较麻烦了,毕竟反比不是那么好确定的。
    于是就有了现在最为流行的0px设值法。看似让人难以理解的layout_height=0px的写法,结合layout_weight,却可以使控件成正比例显示,轻松解决了当前Android开发最为头疼的碎片化问题之一。
    先看下面的stylesstyle_layout.xml
复制代码
<?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_widthlayout_height两个属性被我封装成了4style
    根据实际布局情况,选用当中的一种,不需要自己设置,看过我前一个ActivityGroupDemo的同学应该非常熟悉了
    然后我的Demo的布局如下(weight_layout.xml
复制代码
<?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>
复制代码

最后我们在ActivityonCreate方法里这么做 

复制代码
// 第一个按钮,宽度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


0 0
原创粉丝点击