Android多屏幕适配全攻略

爱财科技移动分享站2019-02-10 13:43:08

目录 




前言


     Android仅是一个基于Linux的平台系统,该系统已经很好融入到我们的生活当中,比如手机、电视、车载媒体等,据友盟指数显示,统计至2015年12月,支持Android的设备共有27796种。显示的内容会根据因为设备屏幕的大小与密度而有着显著的区别,因为在如今的市场上Android系统、屏幕尺寸、屏幕密度是一种碎片化的存在,本节将会详细的为你解释一些关于分辨率与精度的一些基层概念,以及如何处理关于屏幕多分辨率的支持,下图为碎片化的统计图。


定义


     使得某一个元素在Android不同尺寸、不同分辨率的手机上具备相同的显示效果。


术语


屏幕尺寸:

  • 含义:手机对角线的物理尺寸

  • 单位:英寸(inch),1英寸=2.54cm

  • 注释:Android手机主流屏幕尺寸有4.7寸,5.0寸,5.5寸,6.0寸等

 


 屏幕分辨率:

  • 含义:手机横、纵向上像素点总和

  • 单位:px(pixel),1px=1像素点

  • 注释:分辨率一般描述成“高*宽”,如2560*1440,指的是在高的方向有2560像素,在宽的方向上有1440像素,2k屏幕的意思是2560*1440,4k屏幕的意思是3840*2160。国内市面上Android设备不同分辨率的市场占有比(图片来源于OpenSignalMaps):


       


 屏幕像素密度

  • 含义:每英寸像素的点数

  • 单位:dpi(dots per inch)

  • 注释:假如一英寸里有160个像素,这个屏幕的像素密度是160dpi,1dpi=1px。


 

以上三者所存在的联系,如 5寸屏幕,宽高为宽高为1080*1920,则该手机屏幕密度(dpi)= 斜边/尺寸。

    


 密度无关像素

  • 含义:density-independent pixel

  • 单位:dp

  • 注释:该单位与设备终端并无直接关系,这是Android一个为了适配屏幕碎片化所产生的一个特有的单位,dp能够让同一数值在不同的分辨率展示出大致相同的尺寸大小。但是当设备的尺寸差异较大的时候,需要进行单独处理,这里我们暂且不提,在文后会有解决方案。

    dp=px * 160/dpi(规定以480*320屏幕的分辨率为基准)

    左图是红米标配,右图是红米高配。请看左图,可以得出dpi为320,即是720屏幕的手机为例,所以dp=px*160/320=px/2。

    


 独立比例像素

  • 含义:scale   independent pixels 

  • 单位: sp或sip

  • 注释:Android推荐的字体大小使用单位,同样与终端无关,字体除了数值设置外,还受到系统字体大小设置的影响,而使用sp可以适应这种变化,dp则不会跟随系统字体大小设置的变化而变化,并且不推荐使用奇数字体大小,容易造成操作精度的丢失。


解决方案:


  一.布局元素自适应屏幕

  • 使用场景:页面布局设计中

  • 做法:使用相对布局(RelativeLayout)和线性布局(LinearLayout),禁用绝对布局(AbsoulteLayout)

  • 在使用相对布局同时也要考虑渲染画面所占用的内存,相对布局渲染耗时差不多是线性布局的3倍左右,但线性布局无法准去控制子视图之间的关系,在具体开发中选择哪种布局得按具体需求来选择。官方文档给出了一个很好的例子,让我们一起来欣赏下RelativeLayout布局的强大。

通过layout_alignParentXXX和layout_alignXX属性可以确认

    RelativeLayout子类的位置,下面是Demo代码中在2个屏幕上的展现

          


 在小屏幕上的展示:


 在大屏幕上的展示: 


 

 结论:虽说控件大小因为屏幕分辨率的不同有所改变,但几个控件之间的相互位置还是保持不变的。

 

二.布局组件适配

    布局组件的layout_width和layout_height属性尽量使用wrap_content、match_parent。

    使用“wrap_content”,系统就会将试图的宽高设置成所需的最小尺寸以适应试图中的内容,而”match_parent“则会展开组件以匹配其父视图的尺寸,值得注意的是在低于API级别8的系统中称为fill_parent。weight是线性布局(LinearLayout)所特有的属性。

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

     如果宽度为match_parent的的属性,分别设置weight为1和2,得到的结果正好是相反。

  由此我们可以得出android:layout_weight的本质是: 如果子View设置了该属性并且有效,那么该View的宽度等于原有宽度+剩余空间所在比。

 

三.使用限定符

  • 尺寸限定符:

    为了适配市面上多种多样的屏幕,系统为我们提供相对布局这一方法,但Android碎片化的程度超乎我们的想象,不一定都能为每一种屏幕适配。比如手机和平板的屏幕差别是显著的,所以我们还得针对这类情况进行特殊的适配处理。所以我们提出了使用尺寸限定符来解决这一问题,在运行时根据当前的设备自动选择合适的资源文件。

  res/layout/main.xml,单面板布局:

           

   res/layout-large/main.xml,双面板布局:

由两个布局可以看出APP运行在手机和平板上所展现的内容肯定是不一样的。第二种布局名称目录中的large限定符。系统将会在属于较屏幕的设备上选择此布局,屏幕正常的话则不再需要限定符,会自动匹配第一种布局。

  • 最小宽度限定符

该方法只能在Android版本大于3.2的设备上使用,低于Android3.2适配会之后解释。为了适应不同的屏幕,我们可以使用large限定尺寸符进行处理,但仅仅一个larger显然跟不上产品的迭代更新,因此我们得根据不同的屏幕像素密度进行适配。通过下图我们可以知道,不同的屏幕像素密度会找到相应文件夹下面的资源文件,这是系统自动选择的结果。


  • 布局别名

最小宽度限定符仅适用于 Android 3.2 及更高版本。因此,如果我们仍需使用与较低版本兼容的概括尺寸范围(小、正常、大和特大)。例如,如果要将用户界面设计成在手机上显示单面板,但在 7 英寸平板电脑、电视和其他较大的设备上显示多面板,那么我们就需要提供以下文件:

        a.res/layout/main.xml: 单面板布局

        b.res/layout-large: 多面板布局

        c.res/layout-sw600dp: 多面板布局

      后两个文件是相同的,因为其中一个用于和 Android 3.2 设备匹配,而另一个则是为使用较低版本 Android 的平板电脑和电视准备的。

      要避免平板电脑和电视的文件出现重复(以及由此带来的维护问题),您可以使用别名文件。例如,您可以定义以下布局。

        res/layout/main.xml,单面板布局

        res/layout/main_twopanes.xml,双面板布局

然后添加这两个文件:

res/values-large/layout.xml:

 

res/values-sw600dp/layout.xml:

 

    后两个文件的内容相同,但它们并未实际定义布局。它们只是将 main 设置成了 main_twopanes 的别名。由于这些文件包含 large 和 sw600dp 选择器,因此无论 Android 版本如何,系统都会将这些文件应用到平板电脑和电视上(版本低于 3.2 的平板电脑和电视会匹配 large,版本高于 3.2 的平板电脑和电视则会匹配 sw600dp。

四.图片资源

    本质是图片在不同设备上所展现的内容都达到预期的效果,在不同屏幕密度文件下面放不同尺寸的设计图,通过@+drawable/id属性,系统都能根据相应屏幕的 屏幕密度(dpi)自动选取合适的位图。

  • 某些场景建议使用.9图片,.9的图片是为了防止图片拉伸所造成的失真变形,是Android系统上一种特有的图片格式,.9图片经常会在聊天对话背景,按钮背景灯地方用到,点九图格式规定由左侧和上侧来控制图片的拉伸,右侧和下侧控制文字的显示区域,具体的实现可以自行查阅资料哦:)

  • 本地保存的图片建议使用.png的图片,png是无损压缩,有透明通道的。Google近段时间还提出了webPag图片,可以使图片加载更快,所占的空间更小。

百分比适配

    本质是在项目中针对你所需要适配的手机屏幕的分辨率各自创建一个文件夹,看下图:

 

 

然后我们根据一个基准,为基准的意思就是:比如480*320的分辨率为基准

    宽度为320,将任何分辨率的宽度分为320份,取值为x1-x320

    高度为480,将任何分辨率的高度分为480份,取值为y1-y480


 例如对于800*480的宽度480:

 可以看到x1 = 480 / 基准 = 480 / 320 = 1.5 ;其他分辨率类似~~ ,目前Google已支持该方法了。

可具体参考此篇博客: http://blog.csdn.net/lmj623565791/article/details/46767825


总结


      以上就是今天的内容,还有很多有待完善的地方,如果发现有待商榷的问题请在后台给我们留言,我们会第一时间进行回复并改正。图片侵删,enjoy :)

 


Copyright © 丰城计算器学习组@2017