Android多终端适配是我们在实际开发中必然会遇到也必然要解决的问题,解决多终端适配的方法有很多,比如使用百分比布局库(percent-support-lib)、在res目录下生成不同文件下的dimen值、尽量的使用wrap_content/match_parent/weight权重、尽量用dp替代px 文字使用sp做为单位等。

   Android为什么会出现屏幕适配的问题

            由于Android系统的开放性,任何用户、开发者、OEM厂商、运营商都可以对Android进行定制,修改成他们想要的样子。但是这种“碎片化”到底到达什么程度呢?

在2012年,OpenSignalMaps(以下简称OSM)发布了第一份Android碎片化报告,统计数据表明,

                2012年,支持Android的设备共有3997种。

                2013年,支持Android的设备共有11868种。

                2014年,支持Android的设备共有18796种到

        到目前为止就更多了,千千万万的Android机型,屏幕尺寸这么多,为了让我们开发的程序能够比较美观的显示在不同尺寸、分辨率、像素密度(这些概念我会在下面详细讲解)的设备上,那就要在开发的过程中进行的处理问题了。

        重要概念

                什么是屏幕尺寸、屏幕分辨率、屏幕像素密度?

               什么是dp、dip、dpi、sp、px?他们之间的关系是什么?

               什么是mdpi、hdpi、xdpi、xxdpi?如何计算和区分?

    屏幕尺寸

             屏幕尺寸指屏幕的对角线的长度,单位是英寸,1英寸=2.54厘米    比如常见的屏幕尺寸有2.4、2.8、3.5、3.7、4.2、5.0、5.5、6.0等

    屏幕分辨率

             屏幕分辨率是指在横纵向上的像素点数,单位是px,1px=1个像素点。一般以纵向像素*横向像素,如1960*1080。

     屏幕像素密度

          屏幕像素密度是指每英寸上的像素点数,单位是dpi,即“dot per inch”的缩写。屏幕像素密度与屏幕尺寸和屏幕分辨率有关,在单一变化条件下,屏幕尺寸越小、分辨率越      高,像素密度越大,反之越小。

      dp、dip、dpi、sp、px

           px我们应该是比较熟悉的,前面的分辨率就是用的像素为单位,大多数情况下,比如UI设计、Android原生API都会以px作为统一的计量单位,像是获取屏幕宽高等。

      dip和dp是一个意思,都是Density Independent Pixels的缩写,即密度无关像素,上面我们说过,dpi是屏幕像素密度,假如一英寸里面有160个像素,这个屏幕的像素密度       就是160dpi,那么在这种情况下,dp和px如何换算呢?在Android中,规定以160dpi为基准,1dip=1px,如果密度是320dpi,则1dip=2px,以此类推。

     mdpi、hdpi、xdpi、xxdpi

         mdpi、hdpi、xdpi、xxdpi用来修饰Android中的drawable文件夹及values文件夹,用来区分不同像素密度下的图片和dimen值。

         在进行开发的时候,我们需要把合适大小的图片放在合适的文件夹里面

   1、使用百分比布局库(Android-percent-support)

两种布局供大家使用

             PercentRelativeLayout、PercentFragmentLayout,顾名思义这是继承自RelativeLayout和FragmentLayou两个容器类

          支持的属性有:

   layout_widthPercent:占父控件宽度百分百

      layout_heightPercent:占父控件高度百分百

      layout_marginPercentlayout_marginLeftPercentlayout_marginTopPercentlayout_marginRightPercent
layout_marginBottomPercentlayout_marginStartPercentlayout_marginEndPercent

      这些属性一看就明白它的意思

      使用:它的使用比较简单,github上也有源码Android-percent-support-lib-sample

         首先在build.gradle中添加

     compile 'com.android.support:percent:22.2.0'
     然后就可以用它来进行布局,看下面的效果图,简单明了


      

2、在res目录下生成不同分辨率下的dimens文件

    目录结构大致如下,你可以点击我下载这个工具

   

这个时候我们就可以尽情的写具体的数值了,比如:layout_marginLeft="@dimen/dimen_30_dip",这个基准尺寸就是设计图尺寸,如果UI设计师给你的设计图就是480*800你用工具生成的基准也是480*800的话就无需要对标注进行换算,设计图伤标注的是多少,layout中就直接写具体的数值也是没问题的

存在的弊端:

对于没有考虑到屏幕尺寸,可能会出现意外的情况

apk的大小会增加;


3、使用wrap_content、match_parent、weight


要确保布局的灵活性并适应各种尺寸的屏幕,应使用 “wrap_content” 和 “match_parent” 控制某些视图组件的宽度和高度。

使用 “wrap_content”,系统就会将视图的宽度或高度设置成所需的最小尺寸以适应视图中的内容,而 “match_parent”(在低于 API 级别 8 的级别中称为 “fill_parent”)则会展开组件以匹配其父视图的尺寸。

如果使用 “wrap_content” 和 “match_parent” 尺寸值而不是硬编码的尺寸,视图就会相应地仅使用自身所需的空间或展开以填满可用空间。此方法可让布局正确适应各种屏幕尺寸和屏幕方向。

下面是一段示例代码

下图是在横纵屏切换的时候的显示效果,我们可以看到这样可以很好的适配屏幕尺寸的变化。

weight是线性布局的一个独特的属性,我们可以使用这个属性来按照比例对界面进行分配,完成一些特殊的需求。

但是,我们对于这个属性的计算应该如何理解呢?

首先看下面的例子,我们在布局中这样设置我们的界面

我们在布局里面设置为线性布局,横向排列,然后放置两个宽度为0dp的按钮,分别设置weight为1和2,在效果图中,我们可以看到两个按钮按照1:2的宽度比例正常排列了,这也是我们经常使用到的场景,这是时候很好理解,Button1的宽度就是1/(1+2) = 1/3,Button2的宽度则是2/(1+2) = 2/3,我们可以很清楚的明白这种情景下的占比如何计算。

但是假如我们的宽度不是0dp(wrap_content和0dp的效果相同),则是match_parent呢?

下面是设置为match_parent的效果

我们可以看到,在这种情况下,占比和上面正好相反,这是怎么回事呢?说到这里,我们就不得不提一下weight的计算方法了。

android:layout_weight的真实含义是:如果View设置了该属性并且有效,那么该 View的宽度等于原有宽度(android:layout_width)加上剩余空间的占比。

从这个角度我们来解释一下上面的现象。在上面的代码中,我们设置每个Button的宽度都是match_parent,假设屏幕宽度为L,那么每个Button的宽度也应该都为L,剩余宽度就等于L-(L+L)= -L。

Button1的weight=1,剩余宽度占比为1/(1+2)= 1/3,所以最终宽度为L+1/3*(-L)=2/3L,Button2的计算类似,最终宽度为L+2/3(-L)=1/3L。

这是在水平方向上的,那么在垂直方向上也是这样吗?

下面是测试代码和效果

如果是垂直方向,那么我们应该改变的是layout_height的属性,下面是0dp的显示效果

下面是match_parent的显示效果,结论和水平是完全一样的

虽然说我们演示了match_parent的显示效果,并说明了原因,但是在真正用的时候,我们都是设置某一个属性为0dp,然后按照权重计算所占百分比。

使用相对布局,禁用绝对布局

在开发中,我们大部分时候使用的都是线性布局、相对布局和帧布局,绝对布局由于适配性极差,所以极少使用。

由于各种布局的特点不一样,所以不能说哪个布局好用,到底应该使用什么布局只能根据实际需求来确定。我们可以使用 LinearLayout 的嵌套实例并结合 “wrap_content” 和 “match_parent”,以便构建相当复杂的布局。不过,我们无法通过 LinearLayout 精确控制子视图的特殊关系;系统会将 LinearLayout 中的视图直接并排列出。

如果我们需要将子视图排列出各种效果而不是一条直线,通常更合适的解决方法是使用 RelativeLayout,这样就可以根据各组件之间的特殊关系指定布局了。例如,我们可以将某个子视图对齐到屏幕左侧,同时将另一个视图对齐到屏幕右侧。

下面的代码以官方Demo为例说明。

在上面的代码中我们使用了相对布局,并且使用alignXXX等属性指定了子控件的位置,下面是这种布局方式在应对屏幕变化时的表现

在小尺寸屏幕的显示

在平板的大尺寸上的显示效果

虽然控件的大小由于屏幕尺寸的增加而发生了改变,但是我们可以看到,由于使用了相对布局,所以控件之前的位置关系并没有发生什么变化,这说明我们的适配成功了。




    

更多相关文章

  1. android实现视频播放器
  2. Android(安卓)ListView基础篇
  3. Android(安卓)Fragment的介绍与使用(案例Demo)
  4. Android简单视频播放器之VideoView(一)
  5. Android(安卓)UI控件之CheckBox实现墨迹天气设置布局界面(漂亮)
  6. 【转】Android自适应不同分辨率或不同屏幕大小的layout布局(横屏
  7. Android开发之旅:深入分析布局文件
  8. Android(安卓)4.0 Launcher源码分析系列(一)
  9. Android(安卓)Material Design:CoordinatorLayout与NestedScrollV

随机推荐

  1. 扩展Azure VM OS disk(windows 和Linux)
  2. python-形参与实参-01
  3. Linux入侵检测常用命令
  4. Linux下PHP 5.2 Oracle客户端扩展(OCI8)安
  5. Ubuntu奠基人:沉着软件之花将各处怒放
  6. kafka环境搭建二---Windows客户端Linux服
  7. NTP没有正确地在池服务器上处理限制
  8. Linux下的进程间通信
  9. Linux工具之Vim使用
  10. Linux系统下用C语言获取MAC地址