美文网首页Android
Android 屏幕适配

Android 屏幕适配

作者: 西小瓜 | 来源:发表于2019-08-27 09:38 被阅读0次

    1.关于 Android 屏幕适配

    1.1 什么是 Android 屏幕适配

    使得一些元素在 Android 不同尺寸,不同分辨率的手机上具备相同且合适的显示效果。

    1.2 为什么要进行 Android 屏幕适配
    • Android 碎片化:由于Android系统的开放性,任何用户、开发者、硬件厂商、运营商都可以对Android系统和硬件进行定制,修改成他们想要的样子。
      • Android 系统碎片化:基于Google原生系统,小米定制的MIUI、魅族定制的flyme、华为定制的EMUI等
      • Android 屏幕尺寸碎片化:5寸、5.5寸、6寸等
      • Android屏幕分辨率碎片化:320x480、480x800、720x1280、1080x1920等
    • 导致的结果:容易出现同一元素在不同手机上显示效果不同的问题
    • 综上:为了保证用户获得一致的用户体验效果,使得某一元素在Android不同尺寸、不同分辨率的、不同系统的手机上具备相同的显示效果,能够保持界面上的效果一致,我们需要对各种手机屏幕进行适配

    2.相关重要概念

    2.1 屏幕尺寸

    指屏幕的对角线的长度

    单位是英寸,1英寸=2.54厘米,常见的屏幕尺寸有2.4、2.8、3.5、3.7、4.2、5.0、5.5、6.0等

    2.2 屏幕分辨率

    指在横纵向上的像素点数

    单位是px,1px=1个像素点。一般以纵向像素* 横向像素,如1960*1080

    2.3 屏幕像素密度

    指每英寸上的像素点数

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

    2.3 dp,dip,dpi,sp,px
    • dp:和dip 是一个意思,都是Density Independent Pixels的缩写,即密度无关像素
    • dpi:屏幕像素密度,假如一英寸里面有160个像素,这个屏幕的像素密度就是160dpi
    • dp与px的转换:

    ui设计师给我们的设计图是以px为单位的,Android开发则是使用dp作为单位的,那么我们需要进行转换,在Android中,规定以160dpi为基准,1dip=1px,如果密度是320dpi,则1px=2dp,具体如下表:

    密度类型 代表的分辨率(px) 屏幕密度(dpi) 换算(px/dp) 比例
    低密度(ldpi) 240x320 120 1px=0.75dp 3
    中密度(mdpi) 320x480 160 1px=1dp 4
    高密度(hdpi) 480x800 240 1px=1.5dp 6
    超高密度(xhdpi) 720x1280 320 1px=2dp 8
    超超高密度(xxhdpi) 1080x1920 480 1px=3dp 12
    转换过程 转换公式 示例
    dp单位转换成px单位 px = dp* (devicePixelRatio)= dp*(density/160) 假如density(像素密度)为320,把360dp转换成px,那么最终像素=360dp*(320/160)=720px
    px单位转换成dp单位 dp = px * (devicePixelRatio)=px * (density/160) 假如density(像素密度)为320,把640dp转换成px,那么最终像素=640dp*(320/160)=1280px
    • 使用px作为单位的,在不同的设备中会显示不同的效果,使用dp作为单位的,会根据不同的设备进行转化,适配不同机型。所以建议在长度宽度的数值使用dp作为单位
    • 使用sp作为字体大小单位,会随着系统的字体大小改变,而dp作为单位则不会。所以建议在字体大小的数值要使用sp作为单位
    2.4 mdpi,hdpi,xdpi,xxdpi

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

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

    • 如何区分?Google官方指定按照下列标准进行区分:
    名称 像素密度范围
    mdpi 120dpi~160dpi
    hdpi 160dpi~240dpi
    xhdpi 240dpi~320dpi
    xxhdpi 320dpi~480dpi
    xxxhdpi 480dpi~640dpi
    名称 图标尺寸
    mdpi 48x48px
    hdpi 72x72px
    xhdpi 96x96px
    xxhdpi 144x144px
    xxxhdpi 192x192px

    3.解决方案:(如何适配)

    3.1 支持各种屏幕尺寸
    3.1.1 使用 wrap_content,match_parent,weight
    3.1.2 使用相对布局,禁用绝对布局(绝对布局适配性差)
    • 效果:使得不同元素自适应屏幕尺寸
    3.1.3 使用限定符

    通过布局拉伸组件内外的空间以适应各种屏幕,但它们不一定能为每种屏幕都提供最佳的用户体验,应该应针对各种屏幕配置提供一些备用布局,故使用限定符,在运行时根据当前的设备配置自动选择合适的资源了,例如根据各种屏幕尺寸选择不同的布局。

    a 使用尺寸限定符
    • 使用场景:当一款应用显示的内容较多,希望进行以下设置
    • 在平板电脑和电视的屏幕(>7英寸)上:实施“双面板”模式以同时显示更多内容
    • 在手机较小的屏幕上:使用单面板分别显示内容

    因此,我们可以使用尺寸限定符(layout-large)通过创建一个文件来完成上述设定:

    res/layout-large/main.xml
    

    文件配置如下:

    • 适配手机的单面板(默认)布局:res/layout/main.xml
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <fragment android:id="@+id/headlines"
                  android:layout_height="fill_parent"
                  android:name="com.example.android.newsreader.HeadlinesFragment"
                  android:layout_width="match_parent" />
    </LinearLayout>
    
    • 适配尺寸>7寸平板的双面板布局::res/layout-large/main.xml
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="horizontal">
        <fragment android:id="@+id/headlines"
                  android:layout_height="fill_parent"
                  android:name="com.example.android.newsreader.HeadlinesFragment"
                  android:layout_width="400dp"
                  android:layout_marginRight="10dp"/>
        <fragment android:id="@+id/article"
                  android:layout_height="fill_parent"
                  android:name="com.example.android.newsreader.ArticleFragment"
                  android:layout_width="fill_parent" />
    </LinearLayout>
    
    • 请注意:这种方式只适合Android 3.2版本之前
    • 两个布局名称均为main.xml,只有布局的目录名不同:第一个布局的目录名为:layout,第二个布局的目录名为:layout-large,包含了尺寸限定符(large)
    • 被定义为大屏的设备(7寸以上的平板)会自动加载包含了large限定符目录的布局,而小屏设备会加载另一个默认的布局
    b. 最小宽度(Smallest-width)限定符
    • 背景:上述提到的限定符“large”具体是指多大呢?似乎没有一个定量的指标,这便意味着可能没办法准确地根据当前设备的配置(屏幕尺寸)自动加载合适的布局资源
    • 例子:比如说large同时包含着5寸和7寸,这意味着使用“large”限定符的话我没办法实现为5寸和7寸的平板电脑分别加载不同的布局

    最小宽度限定符可让您通过指定某个最小宽度(以 dp 为单位)来定位屏幕。例如,标准 7 英寸平板电脑的最小宽度为 600 dp,因此如果您要在此类屏幕上的用户界面中使用双面板(但在较小的屏幕上只显示列表),您可以使用上文中所述的单面板和双面板这两种布局,但您应使用 sw600dp 指明双面板布局仅适用于最小宽度为 600 dp 的屏幕,而不是使用 large 尺寸限定符。

    • res/layout/main.xml,单面板(默认)布局:
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <fragment android:id="@+id/headlines"
                  android:layout_height="fill_parent"
                  android:name="com.example.android.newsreader.HeadlinesFragment"
                  android:layout_width="match_parent" />
    </LinearLayout>
    
    • res/layout-sw600dp/main.xml,双面板布局:
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="horizontal">
        <fragment android:id="@+id/headlines"
                  android:layout_height="fill_parent"
                  android:name="com.example.android.newsreader.HeadlinesFragment"
                  android:layout_width="400dp"
                  android:layout_marginRight="10dp"/>
        <fragment android:id="@+id/article"
                  android:layout_height="fill_parent"
                  android:name="com.example.android.newsreader.ArticleFragment"
                  android:layout_width="fill_parent" />
    </LinearLayout>
    

    也就是说,对于最小宽度大于等于 600 dp 的设备,系统会选择 layout-sw600dp/main.xml(双面板)布局,否则系统就会选择 layout/main.xml(单面板)布局。

    Android 版本低于 3.2 的设备不支持此技术,原因是这些设备无法将 sw600dp 识别为尺寸限定符,因此我们仍需使用 large 限定符

    3.1.4 使用布局别名
    • 场景:

    当你需要同时为Android 3.2版本前和Android 3.2版本后的手机进行屏幕尺寸适配的时候,由于尺寸限定符仅用于Android 3.2版本前,最小宽度限定符仅用于Android 3.2版本后,所以这会带来一个问题,为了很好地进行屏幕尺寸的适配,你需要同时维护layout-sw600dp和layout-large的两套main.xml平板布局,如下:

    适配手机的单面板(默认)布局:res/layout/main.xml

    适配尺寸>7寸平板的双面板布局(Android 3.2前):res/layout-large/main.xml

    适配尺寸>7寸平板的双面板布局(Android 3.2后)res/layout-sw600dp/main.xml

    最后的两个文件的xml内容是完全相同的,这会带来:文件名的重复从而带来一些列后期维护的问题

    于是为了要解决这种重复问题,我们引入了“布局别名”

    还是上面的例子,你可以定义以下布局:

    • 适配手机的单面板(默认)布局:res/layout/main.xml
    • 适配尺寸>7寸平板的双面板布局:res/layout/main_twopanes.xml

    然后加入以下两个文件,以便进行Android 3.2前和Android 3.2后的版本双面板布局适配:

    1. res/values-large/layout.xml(Android 3.2之前的双面板布局)
    <resources>
        <item name="main" type="layout">@layout/main_twopanes</item>
    </resources>
    
    1. res/values-sw600dp/layout.xml(Android 3.2及之后的双面板布局)
    <resources>
    <item name="main" type="layout">@layout/main_twopanes</item>
    </resources>
    
    • 由于这些文件包含 large 和 sw600dp 选择器,因此,系统会将此文件匹配到不同版本的>7寸平板上:
      a. 版本低于 3.2 的平板会匹配 large的文件
      b. 版本高于 3.2 的平板会匹配 sw600dp的文件
    • 最后两个文件有着相同的内容,但是它们并没有真正去定义布局,它们仅仅只是将main设置成了@layout/main_twopanes的别名
    3.1.5 .使用自动拉伸位图

    图片资源能够适应各种尺寸

    • 解决方法:自动拉伸位图,这是一种格式特殊的 PNG 文件,其中会指明可以拉伸以及不可以拉伸的区域

    参考链接

    相关文章

      网友评论

        本文标题:Android 屏幕适配

        本文链接:https://www.haomeiwen.com/subject/dhssectx.html