Android 适配的点点滴滴

2024-05-05 17:38
文章标签 android 适配 点点滴滴

本文主要是介绍Android 适配的点点滴滴,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

温馨提示:阅读本文需要10分钟

一、为什么要进行 Android 屏幕适配

由于 Android 系统的开放性,任何用户、开发者、OEM 厂商、运营商都可以对 Android 进行定制,于是导致:

  • Android 系统碎片化: 小米定制的 MIUI、魅族定制的 flyme、华为定制的 EMUI 等等——当然都是基于 Google 原生系统定制的;
  • Android 机型屏幕尺寸碎片化: 5 寸、5.5 寸、6 寸等等;
  • Android 屏幕分辨率碎片化: 320x480、480x800、720x1280、1080x1920。

屏幕尺寸分布图

据友盟指数显示,统计至 2015 年 12 月,支持 Android 的设备共有 27796 种。当 Android 系统、屏幕尺寸、屏幕密度出现碎片化的时候,就很容易出现同一元素在不同手机上显示不同的问题。 
虽然系统为使您的应用适用于不同的屏幕,会进行缩放和大小调整,但您应针对不同的屏幕尺寸和密度优化应用。

这样可以最大程度优化所有设备上的用户体验,用户会认为您的应用实际上是专为他们的设备而设计,而不是简单地拉伸以适应其设备屏幕。

二、相关概念

1. 屏幕尺寸

  • 含义:按屏幕对角测量的实际物理尺寸。
  • 为简便起见,Android 将所有实际屏幕尺寸分组为四种通用尺寸:小、 正常、大和超大
  • 单位:英寸(inch),一英寸≈2.54cm

2. 分辨率

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

一般描述成屏幕的”宽 x 高”=AxB 
含义:屏幕在横向方向(宽度)上有 A 个像素点,在纵向方向(高)有 B 个像素点。 
例子:1080x1920,即宽度方向上有 1080 个像素点,在高度方向上有 1920 个像素点

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

UI 设计师的设计图会以 px 作为统一的计量单位。

  • Android 手机常见的分辨率:320x480、480x800、720x1280、1080x1920

3. 屏幕像素密度

  • 含义:每英寸的像素点数
  • 单位:dpi(dots per ich)

假设设备内每英寸有 160 个像素,那么该设备的屏幕像素密度=160dpi

安卓手机对于每类手机屏幕大小都有一个相应的屏幕像素密度:

密度类型代表的分辨率(px)屏幕像素密度(dpi)
低密度(ldpi)240x320120
中密度(mdpi)320x480160
高密度(hdpi)480x800240
超高密度(xhdpi)720x1280320
超超高密度(xxhdpi)1080x1920480

4. 屏幕尺寸、分辨率、像素密度三者关系

一部手机的分辨率是宽 x 高,屏幕大小是以寸为单位,那么三者的关系是:

5. 密度无关像素 (dp)

  • 含义:density-independent pixel,叫 dp 或 dip,与终端上的实际物理像素点无关。
  • 单位:dp,可以保证在不同屏幕像素密度的设备上显示相同的效果
  • Android 开发时用 dp 而不是 px 单位设置图片大小,是 Android 特有的单位

场景:假如同样都是画一条长度是屏幕一半的线,如果使用 px 作为计量单位,那么在 480x800 分辨率手机上设置应为 240px;在 320x480 的手机上应设置为 160px,二者设置就不同了;如果使用 dp 为单位,在这两种分辨率下,160dp 都显示为屏幕一半的长度。

  • dp 与 px 的转换

因为 UI 设计师给你的设计图是以 px 为单位的,Android 开发则是使用 dp 作为单位的,那么我们需要进行转换:

密度类型代表的分辨率(px)屏幕像素密度(dpi)换算(px/dp)比例
低密度(ldpi)240x3201201dp=0.75px3
中密度(mdpi)320x4801601dp=1px4
高密度(hdpi)480x8002401dp=1.5px6
超高密度(xhdpi)720x12803201dp=2px8
超超高密度(xxhdpi)1080x19204801dp=3px12

在 Android 中,规定以 160dpi(即屏幕分辨率为 320x480)为基准:1dp=1px

6. 独立比例像素

  • 含义:scale-independent pixel,叫 sp 或 sip
  • 单位:sp

Android 开发时用此单位设置文字大小,可根据字体大小首选项进行缩放。

推荐使用 12sp、14sp、18sp、22sp 作为字体设置的大小,不推荐使用奇数和小数,容易造成精度的丢失问题;小于 12sp 的字体会太小导致用户看不清。

三、如何适配

1. 布局适配

使用相对布局(RelativeLayout),禁用绝对布局(AbsoluteLayout)

开发中,我们使用的布局一般有:

  • 线性布局(Linearlayout)
  • 相对布局(RelativeLayout)
  • 帧布局(FrameLayout)
  • 绝对布局(AbsoluteLayout)

由于绝对布局(AbsoluteLayout)适配性极差,所以极少使用。 
对于线性布局(Linearlayout)、相对布局(RelativeLayout)和帧布局(FrameLayout)需要根据需求进行选择,但要记住:

  • 相对布局 RelativeLayout

布局的子控件之间使用相对位置的方式排列,因为 RelativeLayout 讲究的是相对位置,即使屏幕的大小改变,视图之前的相对位置都不会变化,与屏幕大小无关,灵活性很强

  • 线性布局 LinearLayout

通过多层嵌套 LinearLayout 和组合使用“wrap_content”和“match_parent”已经可以构建出足够复杂的布局。但是 LinearLayout 无法准确地控制子视图之间的位置关系,只能简单的一个挨着一个地排列。

所以,对于屏幕适配来说,使用相对布局(RelativeLayout)将会是更好的解决方案。

根据屏幕的配置来加载相应的 UI 布局

最小宽度(Smallest-width)限定符

在 Android 3.2 及之后版本,引入了最小宽度(Smallest-width)限定符

定义:通过指定某个最小宽度(以 dp 为单位)来精确定位屏幕从而加载不同的 UI 资源

  • 使用场景:

你需要为标准 7 英寸平板电脑匹配双面板布局(其最小宽度为 600 dp),在手机(较小的屏幕上)匹配单面板布局

  • 解决方案:您可以使用上文中所述的单面板和双面板这两种布局,但您应使用 sw600dp 指明双面板布局仅适用于最小宽度为 600 dp 的屏幕,而不是使用 large 尺寸限定符。

sw xxxdp,即 small width 的缩写,其不区分方向,即无论是宽度还是高度,只要大于 xxxdp,就采用次此布局

例子:使用了 layout-sw 600dp 的最小宽度限定符,即无论是宽度还是高度,只要大于 600dp,就采用 layout-sw 600dp 目录下的布局

代码展示:

(1)适配手机的单面板(默认)布局: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>

(2)适配尺寸>7 寸平板的双面板布局: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 系统自动选择的)

2. 布局组件适配

本质:使得布局组件自适应屏幕尺寸

  • 做法

使用”wrap_content”、”match_parent”和”weight“来控制视图组件的宽度和高度。 
“wrap_content”:相应视图的宽和高就会被设定成所需的最小尺寸以适应视图中的内容 
“match_parent”(在 Android API 8 之前叫作”fill_parent”):视图的宽和高延伸至充满整个父布局 
“weight” 
- 定义:是线性布局(Linelayout)的一个独特比例分配属性 
- 作用:使用此属性设置权重,然后按照比例对界面进行空间的分配,公式计算是:控件宽度=控件设置宽度+剩余空间所占百分比宽幅

通过使用”wrap_content”、”match_parent”和”weight”来替代硬编码的方式定义视图大小&位置,你的视图要么仅仅使用了需要的那边一点空间,要么就会充满所有可用的空间,即按需占据空间大小,能让你的布局元素充分适应你的屏幕尺寸。

3. 图片资源适配

本质:使得图片资源在不同屏幕密度上显示相同的像素效果

  • 做法:使用自动拉伸位图:Nine-Patch 的图片类型 
    假设需要匹配不同屏幕大小,你的图片资源也必须自动适应各种屏幕尺寸

使用场景:一个按钮的背景图片必须能够随着按钮大小的改变而改变。 
使用普通的图片将无法实现上述功能,因为运行时会均匀地拉伸或压缩你的图片

  • 解决方案:使用自动拉伸位图(nine-patch 图片),后缀名是.9.png,它是一种被特殊处理过的 PNG 图片,设计时可以指定图片的拉伸区域和非拉伸区域;使用时,系统就会根据控件的大小自动地拉伸你想要拉伸的部分。
  • 必须要使用.9.png 后缀名,因为系统就是根据这个来区别 nine-patch 图片和普通的 PNG 图片的;
  • 当你需要在一个控件中使用 nine-patch 图片时,如 
    android:background=”@drawable/button”系统就会根据控件的大小自动地拉伸你想要拉伸的部分

4. 进行屏幕密度匹配

“布局控件”匹配

本质:使得布局组件在不同屏幕密度上显示相同的像素效果

  • 做法:使用密度无关像素

    由于各种屏幕的像素密度都有所不同,因此相同数量的像素在不同设备上的实际大小也有所差异,这样使用像素(px)定义布局尺寸就会产生问题。 
    因此,请务必使用密度无关像素 dp 或独立比例像素 sp 单位指定尺寸。

相关概念介绍:

(1)密度无关像素

  • 含义:density-independent pixel,叫 dp 或 dip,与终端上的实际物理像素点无关。
  • 单位:dp,可以保证在不同屏幕像素密度的设备上显示相同的效果

Android 开发时用 dp 而不是 px 单位设置图片大小,是 Android 特有的单位

场景:假如同样都是画一条长度是屏幕一半的线,如果使用 px 作为计量单位,那么在 480x800 分辨率手机上设置应为 240px;在 320x480 的手机上应设置为 160px,二者设置就不同了;如果使用 dp 为单位,在这两种分辨率下,160dp 都显示为屏幕一半的长度。

  • dp 与 px 的转换 
    因为 ui 给你的设计图是以 px 为单位的,Android 开发则是使用 dp 作为单位的,那么该如何转换呢?
密度类型代表的分辨率(px)屏幕像素密度(dpi)换算(px/dp)比例
低密度(ldpi)240x3201201dp=0.75px3
中密度(mdpi)320x4801601dp=1px4
高密度(hdpi)480x8002401dp=1.5px6
超高密度(xhdpi)720x12803201dp=2px8
超超高密度(xxhdpi)1080x19204801dp=3px12

在 Android 中,规定以 160dpi(即屏幕分辨率为 320x480)为基准:1dp=1px

T-Mobile G1(第一款 android 手机)的参数属于 mdpi 区域的,以上就是取 160dpi 作为基准的原因。

(2)独立比例像素

  • 含义:scale-independent pixel,叫 sp 或 sip
  • 单位:sp

Android 开发时用此单位设置文字大小,可根据用户的偏好文字大小/字体大小首选项进行缩放

推荐使用 12sp、14sp、18sp、22sp 作为字体设置的大小,不推荐使用奇数和小数,容易造成精度的丢失问题;小于 12sp 的字体会太小导致用户看不清

所以,为了能够进行不同屏幕像素密度的匹配,我们推荐:

  • 使用 dp 来代替 px 作为控件长度的统一度量单位
  • 使用 sp 作为文字的统一度量单位

可是,请看以下一种场景:

Nexus5 的总宽度为 360dp,我们现在在水平方向上放置两个按钮,一个是 150dp 左对齐,另外一个是 200dp 右对齐,那么中间留有 10dp 间隔;但假如同样地设置在 Nexus S(屏幕宽度是 320dp),会发现,两个按钮会重叠,因为 320dp<200+150dp

从上面可以看出,由于 Android 屏幕设备的多样性,如果使用 dp 来作为度量单位,并不是所有的屏幕的宽度都具备相同的 dp 长度

再次明确,屏幕宽度和像素密度没有任何关联关系

所以说,dp 解决了同一数值在不同分辨率中展示相同尺寸大小的问题(即屏幕像素密度匹配问题),但却没有解决设备尺寸大小匹配的问题。(即屏幕尺寸匹配问题)

当然,我们一开始讨论的就是屏幕尺寸匹配问题,使用 match_parent、wrap_content 和 weight,尽可能少用 dp 来指定控件的具体长宽,大部分的情况我们都是可以做到适配的。

“图片资源”匹配
  • 本质:使得图片资源在不同屏幕密度上显示相同的像素效果

  • 做法:提供备用位图(符合屏幕尺寸的图片资源)

    由于 Android 可在各种屏幕密度的设备上运行,因此我们提供的位图资源应该始终可以满足各类密度的要求:

密度类型代表的分辨率(px)屏幕像素密度(dpi)
低密度(ldpi)240x320120
中密度(mdpi)320x480160
高密度(hdpi)480x800240
超高密度(xhdpi)720x1280320
超超高密度(xxhdpi)1080x1920480
  • 步骤 1:根据以下尺寸范围针对各密度生成相应的图片。

    比如说,如果我们为 xhdpi 设备生成了 200x200 px 尺寸的图片,就应该按照相应比例地为 hdpi、mdpi 和 ldpi 设备分别生成 150x150、100x100 和 75x75 尺寸的图片:

即一套分辨率=一套位图资源(这个当然是 Ui 设计师做了)

  • 步骤 2:将生成的图片文件放在 res/ 下的相应子目录中(mdpi、hdpi、xhdpi、xxhdpi),系统就会根据运行您应用的设备的屏幕密度自动选择合适的图片。

  • 步骤 3:通过引用 @drawable/id,系统都能根据相应屏幕的 屏幕密度(dpi)自动选取合适的位图。

如果是.9 图或者是不需要多个分辨率的图片,放在 drawable 文件夹即可

对应分辨率的图片要正确的放在合适的文件夹,否则会造成图片拉伸等问题。

更好的方案解决“图片资源”适配问题

上述方案是常见的一种方案,这固然是一种解决办法,但缺点在于:

  • 每套分辨率出一套图,为美工或者设计增加了许多工作量
  • 对 Android 工程文件的 apk 包变的很大

那么,有没有一种方法:

  • 保证屏幕密度适配
  • 可以最小占用设计资源
  • 使得 apk 包不变大(只使用一套分辨率的图片资源)
方法介绍

先来理解下 Android 加载资源过程:

Android SDK 会根据屏幕密度自动选择对应的资源文件进行渲染加载(自动渲染)。比如说,SDK 检测到你手机的分辨率是 320x480(dpi=160),会优先到 drawable-mdpi 文件夹下找对应的图片资源;但假设你只在 xhpdi 文件夹下有对应的图片资源文件(mdpi 文件夹是空的),那么 SDK 会去 xhpdi 文件夹找到相应的图片资源文件,然后将原有大像素的图片自动缩放成小像素的图片,于是大像素的图片照样可以在小像素分辨率的手机上正常显示。

具体请看:http://blog.csdn.net/xiebudong/article/details/37040263

所以理论上来说只需要提供一种分辨率规格的图片资源就可以了。

那么应该提供哪种分辨率规格呢?

如果只提供 ldpi 规格的图片,对于大分辨率(xdpi、xxdpi)的手机如果把图片放大就会不清晰。所以需要提供一套你需要支持的最大 dpi 分辨率规格的图片资源,这样即使用户的手机分辨率很小,这样图片缩小依然很清晰。

那么这一套最大 dpi 分辨率规格应该是哪种呢?是现在市面手机分辨率最大可达到 1080X1920 的分辨率(dpi=xxdpi=480)吗?

xhdpi 应该是首选。原因如下:

  • xhdpi 分辨率以内的手机需求量最旺盛:目前市面上最普遍的高端机的分辨率还多集中在 720X1080 范围内(xhdpi),所以目前来看 xhpdi 规格的图片资源成为了首选。
  • 节省设计资源&工作量:在现在的 App 开发中(iOS 和 Android 版本),有些设计师为了保持 App 不同版本的体验交互一致,可能会以 iPhone 手机为基础进行设计,包括后期的切图之类的。

设计师们一般都会用最新的 iPhone6 和 iPhone5s(5s 和 5 的尺寸以及分辨率都一样)来做原型设计,所有参数请看下方:

机型分辨率(px)屏幕尺寸(inch)系统密度(dpi)
iPhone 5s640X11644332
iPhone 61334x7504.7326
iPhone 6 Plus1080x19205400

iPhone 主流的屏幕 dpi 约等于 320, 刚好属于 xhdpi,所以选择 xhdpi 作为唯一一套 dpi 图片资源,可以让设计师不用专门为 Android 端切图,直接把 iPhone 的那一套切好的图片资源放入 drawable-xhdpi 文件夹里就好,这样大大减少的设计师的工作量!


本文转载,原文地址:http://mp.weixin.qq.com/s/wV0vcRQ15dZV_ZORMDJk_A



这篇关于Android 适配的点点滴滴的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/962277

相关文章

Android DataBinding 与 MVVM使用详解

《AndroidDataBinding与MVVM使用详解》本文介绍AndroidDataBinding库,其通过绑定UI组件与数据源实现自动更新,支持双向绑定和逻辑运算,减少模板代码,结合MV... 目录一、DataBinding 核心概念二、配置与基础使用1. 启用 DataBinding 2. 基础布局

Android ViewBinding使用流程

《AndroidViewBinding使用流程》AndroidViewBinding是Jetpack组件,替代findViewById,提供类型安全、空安全和编译时检查,代码简洁且性能优化,相比Da... 目录一、核心概念二、ViewBinding优点三、使用流程1. 启用 ViewBinding (模块级

Android学习总结之Java和kotlin区别超详细分析

《Android学习总结之Java和kotlin区别超详细分析》Java和Kotlin都是用于Android开发的编程语言,它们各自具有独特的特点和优势,:本文主要介绍Android学习总结之Ja... 目录一、空安全机制真题 1:Kotlin 如何解决 Java 的 NullPointerExceptio

Android NDK版本迭代与FFmpeg交叉编译完全指南

《AndroidNDK版本迭代与FFmpeg交叉编译完全指南》在Android开发中,使用NDK进行原生代码开发是一项常见需求,特别是当我们需要集成FFmpeg这样的多媒体处理库时,本文将深入分析A... 目录一、android NDK版本迭代分界线二、FFmpeg交叉编译关键注意事项三、完整编译脚本示例四

Android与iOS设备MAC地址生成原理及Java实现详解

《Android与iOS设备MAC地址生成原理及Java实现详解》在无线网络通信中,MAC(MediaAccessControl)地址是设备的唯一网络标识符,本文主要介绍了Android与iOS设备M... 目录引言1. MAC地址基础1.1 MAC地址的组成1.2 MAC地址的分类2. android与I

Android 实现一个隐私弹窗功能

《Android实现一个隐私弹窗功能》:本文主要介绍Android实现一个隐私弹窗功能,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友一起看看吧... 效果图如下:1. 设置同意、退出、点击用户协议、点击隐私协议的函数参数2. 《用户协议》、《隐私政策》设置成可点击的,且颜色要区分出来res/l

Android实现一键录屏功能(附源码)

《Android实现一键录屏功能(附源码)》在Android5.0及以上版本,系统提供了MediaProjectionAPI,允许应用在用户授权下录制屏幕内容并输出到视频文件,所以本文将基于此实现一个... 目录一、项目介绍二、相关技术与原理三、系统权限与用户授权四、项目架构与流程五、环境配置与依赖六、完整

Android 12解决push framework.jar无法开机的方法小结

《Android12解决pushframework.jar无法开机的方法小结》:本文主要介绍在Android12中解决pushframework.jar无法开机的方法,包括编译指令、框架层和s... 目录1. android 编译指令1.1 framework层的编译指令1.2 替换framework.ja

Android开发环境配置避坑指南

《Android开发环境配置避坑指南》本文主要介绍了Android开发环境配置过程中遇到的问题及解决方案,包括VPN注意事项、工具版本统一、Gerrit邮箱配置、Git拉取和提交代码、MergevsR... 目录网络环境:VPN 注意事项工具版本统一:android Studio & JDKGerrit的邮

Android实现定时任务的几种方式汇总(附源码)

《Android实现定时任务的几种方式汇总(附源码)》在Android应用中,定时任务(ScheduledTask)的需求几乎无处不在:从定时刷新数据、定时备份、定时推送通知,到夜间静默下载、循环执行... 目录一、项目介绍1. 背景与意义二、相关基础知识与系统约束三、方案一:Handler.postDel