android开发:在不同分辨率,不同屏幕密度dpi的平板上的字体大小和布局的自适应

    最近在这家公司做一些android设备上的开发,使用了几款平板进行真机调试,面对不同分辨率,不同屏幕密度dpi的设备,碰到了一些和虚拟机不太一样的情况,在这里和大家分享一下。

1.一些名词的简单理解,后面会有详细说明

       (1)屏幕尺寸:单位英寸(inch),指的是屏幕对角线长度。

  (2)屏幕密度:单位dpi,指的是每inch上可以显示多少像素点即px。

  (3)屏幕分辨率:单位px * px,如1280×800,我使用的小米853×480等,指的是一屏显示多少像素点。

  (4)屏幕无关像素:单位dp/dip,指的是自适应屏幕密度的像素,用于指定控件宽高。

  (5)刻度无关像素:单位sp,指的是自适应字体的像素,用于指定文字大小。


2.关于屏幕密度dpi

密度可以理解为每英寸包含的像素个数(单位是dpi),如果屏幕物理密度是160dpi时,dp和px是等效的。

2.1先说下屏幕密度的计算吧

一个手机或者平板,拿到手就可以看到它的尺寸和分辨率,我接触的几款android设备有一下几种:

(1)小米1(最早出的那一款)4寸屏幕,853×480的分辨率

(2)联想ideatab s6000  10.1寸,1280×800

(3)某款android平板,大小参数规格单找不到了,反正是mdpi 800×480

    思路很简单:由于给了屏幕对角线的长度10.1英寸,再计算对角线上有多少个像素点,就可以计算每英寸包含的像素点数。

已(2)为例,看看怎么计算屏幕密度:√ (1280²+800²)=1509.43,              1509.43÷10.1=149.449

即其屏幕密度为150dpi。

2.2 android系统对屏幕密度的归一化处理

如图,android提供ldpi,mdpi,hdpi,xhdpi,xxhdpi等不同屏幕密度级别,这些都是经过归一化处理的


ldpi低密度屏,屏幕密度为120dpi, 1dp = 0.75px        (由于像素点是物理点,所以用2个像素点来显示3个dp的内容)

mdpi中密度屏屏幕密度160dpi    1dp = 1px

tvdpi电视密度屏屏幕密度213dpi   1dp = 1.33px

hdpi高密度屏屏幕密度240dpi     1dp = 1.5px

xhdpi极高密度屏屏幕密度320dpi   1dp = 2px

小米1屏幕密度为244dpi,属于hdpi级别;(2)款平板密度为150dpi,归一化属于mdpi级别

这样就为你的设备计算好了密度级别,这个很重要

3.屏幕布局layout.xml的适配


3.1不考虑横竖屏切换

参考自:http://www.cnblogs.com/mybkn/articles/2535519.html    点击打开链接

作者给了4种方法,我就copy下我借鉴的第一种方法吧:

目前最为推荐的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_parentitem>  
    <item name="android:layout_height">fill_parentitem>  
  style>
   

  <style name="layout_wrap">  
    <item name="android:layout_width">wrap_contentitem>  
    <item name="android:layout_height">wrap_contentitem>  
  style>
 

  <style name="layout_horizontal" parent="layout_full">  
    <item name="android:layout_width">0pxitem>  
  style> 
    

  <style name="layout_vertical" parent="layout_full">  
    <item name="android:layout_height">0pxitem>  
  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的界面(后面的图也如此),可以看出显示比例和代码中完全一致,我就不多说了,大家对照下就能看出来了。



3.2考虑横竖屏切换

思路是:在res目录下新建立两个文件夹:layout-port和layout-land.
把横屏的xml放到layout-land里,把竖屏的放到layout-port里,取一样的名字。

具体demo木有,boss要求我把屏幕写成横屏,写死了

3.3图片的适配

准备不同大小的图片资源,起一样的名字放在对应的drawable- dpi文件夹下,

                  android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:scaleType="fitCenter"
            android:src="@drawable/xxx"/>

这4个属性必不可少,简单的介绍一下,充满布局,scalType属性设置为fitCenter保证放大长宽比例,src而不是background

再就是图标,icon的一些说明:

ldpi (120 dpi)      mdpi (160 dpi)     hdpi (240 dpi)       xhdpi (320 dpi)

36 x 36 px          48 x 48 px            72 x 72 px          96 x 96 px



4.字体大小的适配

思路是如上图,为不同分辨率,不同密度准备一套字体大小的尺寸

在values-xxx-xxx文件夹下创建dimen。xml文件:



    20sp
    18sp
    10sp

有一些我在配置过程中碰到的问题和大家分享一下:

1.文件夹命名:

    如上图,有些错误的文件夹,我的结论是分辨率x号前面的数值要比后面的大,不然系统无法识别,

注意:乘号的输入法,千万别用汉字输入法下的x,不然系统无法系别,不要问我为什么,我是不会告诉你这玩意花了我起码3个小时才搞明白

2.系统会自动匹配values文件夹

  举个例子,之前提到的(2)1280x800的,如果你创建values-mdpi-1250x800,values-mdpi-1200x800,(注意了这两个都不是1280x800的),最后真机联调的时候,显示的是比真实分辨率小的最大的那套尺寸即values-mdpi-1250x800,而不是1200x800,这点上虚拟机和真机有很大的区别,xml视图只会找1280x800的尺寸,如果没有,他就显示默认大小的字体。

可以参考下这一篇:点击打开链接http://www.cnblogs.com/zealotrouge/archive/2012/11/23/2784774.html

3。如果系统系统自动匹配的时候没有找到最小的尺寸,就会报错

 所以建议在values下dimen.xml下保存一份最小的字体尺寸,再难看也好过报错,是吧


5.字体适配的其他思路

用图片代替字体,但是EditText有点难搞...



暂时总结的就这么多了,第一次发原创~~~

争取以后写的更好

你可能感兴趣的:(android开发)