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

1 篇文章 0 订阅
1 篇文章 0 订阅

在画页面时,常常会出现一个烦恼,页面在不同屏幕大小的手机上  变形了,要么被拉升要么挤到了一块,要么字的大小超出了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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值