
正文
android全面屏适配,安卓全面屏适配问题
提示:扫一扫查出行【扫一扫了解最新限行尾号】
复制提示
Android适配全面屏上下黑边问题
虽然布局全是 match_parent 但是就是有黑边,问题在于Android默认了一个最大的高宽比例,就是高宽比1.86,差不多16:9的常见样式,多出一点来也都能行。但是现在红米6p是19:9 ≈ 2.1??超过默认值很远,很棒棒。只能手动改下配置了。(targetSdkVersion 24应该不会出现这种问题)
在 AndroidManifest.xml 的 application 标签里加入
或者更大,据我了解mix3,19.5:9,越来越长可以写稍微大点留一些余地
或者
在AndroidManifest中针对Activity标签添加
也可以实现全屏显示,但此设置只针对Activity生效,且增加了此属性该activity也会支持分屏显示。
跟多的全面屏适配优化可以看下这篇文章~
Android APP适配全面屏手机的技术要点
以及这个自动适配的方案(和解决黑边问题无关)
今日头条屏幕适配方案终极版正式发布
相关问答
Q1: Android全面屏以及异形屏适配策略
异形屏适配Android 9.0之后,google官方推出了异形屏适配的支持DisplayCutout。通过这个类可以获取到非功能区域的位置与大小,以便应用的内容展示区域很好的避开对应这块区域。在做android P适配时,我们关注windowManager源码会发现:
由此在我们的应用已经做好了异形屏适配的基础上,我们可以允许我们的应用使用刘海区域。那么对于android9.0之前的设备呢?其实主流的手机厂商给了他们各自的一套解决方案。其实市面上刘海屏手机,当你在设置中对特定的应用开启了使用刘海屏区域时,应用不管你有没有做异形屏适配都会将刘海屏区域作为内容展示区域。这样来看,其实就存在着一定的风险,当应用本身没有做异形屏适配,会导致应用显示异常。在这一点,不得不提到华为的做法,华为为了保证应用的质量,特意加了一道开关来控制是否开放刘海屏显示。而这个开关掌握在应用开发者自己手里,应用开发者打开了对应的开关,用户的设置才真的有效,这样有效的保证了应用的质量。
主流的手机厂商都有提供自己的异形屏适配支持的方案。
OPPO:
VIVO:
HUAWEI:
Q2: Android屏幕适配之全面屏适配
从2017年开始,全面屏之战逐渐如火如荼的展开了,那么我们Android程序员又多了一个小事情,就是解决全面屏适配的问题。
全面屏和以前的屏幕相比,有以下几点改变
声明方式
ratio_float这个值怎么取呢?
其实就是高宽比。
传统的手机高宽比是:16 : 9 即 16 / 9 ≈ 1.78
那么全面屏的手机宽高比:18 :9 即 18 / 9 = 2
但是这个时候,我们需要注意一下,现在很多手机都在追求更大的高宽比,即让屏幕顶部和底部边框越小越好,比如现在的「小米 mix 3 」
即他的高宽比是
19.5 / 9 ≈ 2.17
所以保险起见,设置成为 2.2, 当然这个值也不是固定的,如果有更新的手机上市,没准我们还得改。
即这样设定就好了
Android 7.0 google 默认支持了分屏模式,即 Manifest 文件中配置 Activity 的
那么这个时候就不需要再配置上面的 「最大屏幕高宽比」,就可以适配全面屏了。
但是如果通过自定义控件将“分屏模式”禁止的话,就会出现屏幕 上下黑边的效果,非常丑。
修改AndroidManifest.xml文件,设置targetSdkVersion=26,就是应用升级到O版本。
不需要设置其他任何属性,默认在任何纵横比的屏幕都能全屏显示。
(备注:有一种例外情况需要注意,应用如果已经适配到O版本,并且通过meta-data属性android.max_aspect或者是android:MaxAspectRatio属性设置了页面支持的最大纵横比,同时又通过android:resizeableActivity=“false”设置了页面不支持分屏,这个时候系统会按照应用自己设置的最大纵横比决定该页面是否能全屏显示,如果应用设置的最大纵横比比手机屏幕比例小,那应用还是无法全屏显示。)
默认 UI 为我们切的启动页面的图是固定的,比如 1920*1080
这个能适配以前一般的分辨率的手机,但是全面屏的出现,我们会发现,这个启动页的图片会被拉伸,一般是纵向拉伸,因为 “高” 变大了。
那么这种情况的解决方法其实有这么几种思路:
本人还是觉得虚拟导航按键不是一个好东西,但是全面屏的出现,真的把我以前喜欢的"实体按键" 给舍弃掉了。
我倒是觉得替代以前的"实体按键"的最好的方法,还是手势操作。起码我觉得小米8 的手势操作很 6 有没有。再看看苹果,压根就不同虚拟按键考虑好不。。。
不过,这是我自己的拙见,请各位虚拟按键爱好者,不要喷我,先行谢过。
原则,虚拟按钮的显示样式,其实根据当前具体的页面情况进行调整,调整策略其实和status bar 的类似。
可以通过
来定义颜色。
或者通过设置当前activity 主题 或者设置application主题
在主题的样式中设置:
即可。
频繁的手机更新迭代,虽然让我们程序员多了一些事情可做,但是却也是我们喜闻乐见的事,手机在发展,说明我们的行业也在发展呀,况且,解决这些问题也不是难事。你说是不是呢?
如果没看懂我的文章,请观看小米官网提供的方案(其实是一致的):
全面屏及虚拟键适配说明
Q3: 一种非常好用的Android屏幕适配
网上关于屏幕适配的文章已经铺天盖地了,为什么我还要讲?因为网上现在基本都是使用 屏幕分辨率限定符 进行适配,即每种屏幕分辨率的设备需要定义一套 dimens.xml 文件。由于不同分辨率的设备太多了,而且有些设备还有虚拟按键(例如华为手机),这样就还需要每个有虚拟按键的设备加多一套 dimens.xml 文件,再加上平板那些你会发现 dimens.xml 文件所占的体积已经超过 2M 了!这绝对不是我们想要的。
我这里要讲的是使用 swNdp 限定符,即 smallestWidth(最小宽度) 限定符 来进行适配,使用这种方式只需要少量 dimens.xml 文件即可达到适配,而且根本不用考虑虚拟按键的问题。如果只适配手机,dimens.xml 文件所占的体积只有 100 多 KB,即使加上平板和 TV,也就 500 多 KB,完全可以接收。这种方案已经在自己多个项目中应用过了,经过几十台手机测试过,基本不会出现适配有问题的情况。制作生成对应 dimens.xml 文件插件(后面会讲)的作者也说过他在待过的两家大公司实践过,所以请放心使用。
关于为什么要进行屏幕适配,什么是 dp、dpi 这些概念我就不去一一讲解了,网上很多文章。这里我推荐几篇讲的比较好的:
屏幕分辨率限定符适配需要在 res 文件夹下创建各种屏幕分辨率对应的 values-xxx 文件夹,如下图:
然后根据一个基准分辨率,例如基准分辨率为 1280x720,将宽度分成 720 份,取值为 1px~720px,将高度分成 1280 份,取值为 1px~1280px,生成各种分辨率对应的 dimens.xml 文件。如下分别为分辨率 1280x720 与 1920x1080 所对应的横向 dimens.xml 文件:
假设设计图上的一个控件的宽度为 720px,那么布局中就写 android:layout_width="@dimen/x720" ,当运行程序的时候,系统会根据设备的分辨率去寻找对应的 dimens.xml 文件。例如运行在分辨率为 1280x720 的设备上,系统会自动找到对应的 values-1280x720 文件夹下的 lay_x.xml 文件,由上图可知 x720 对应的值为
720.px,可铺满该屏幕宽度。运行在分辨率为 1920x1080 的设备上,系统会自动找到对应的 values-1920x1080 文件夹下的 lay_x.xml 文件,由上图可知 x720 对应的值为 1080.0px,可铺满该屏幕宽度。这样就达到了屏幕适配的要求!
smallestWidth 限定符适配原理与屏幕分辨率限定符适配原理一样,系统都是根据限定符去寻找对应的 dimens.xml 文件。例如程序运行在最小宽度为 360dp 的设备上,系统会自动找到对应的 values-sw360dp 文件夹下的 dimens.xml 文件。区别就在于屏幕分辨率限定符适配是拿 px 值等比例缩放,而 smallestWidth 限定符适配是拿 dp 值来等比缩放而已。需要注意的是“最小宽度”是不区分方向的,即无论是宽度还是高度,哪一边小就认为哪一边是“最小宽度”。如下分别为最小宽度为 360dp 与最小宽度为 640dp 所对应的 dimens.xml 文件:
ScreenUtils—— ScreenUtils
既然原理都一样,都需要多套 dimens.xml 文件,那为什么要选择 smallestWidth 限定符适配呢?
大多数 UI 设计师提供的设计图无非就几种,它们对应的获取方式如下:
这些文件当然不会手动去写,网上已经有大神提供了自动生成这些文件的插件 ScreenMatch 。但是这个插件还是有点问题的:
基于以上问题,我在该插件的源码上优化生成了新的插件 ScreenMatch ,由于插件库已经有原作者的插件了,所以我就不重复造轮子上传到插件库了,你直接用本地安装的方式安装即可。
工具使用步骤:
然后选择在哪个 module 下执行适配。即基于哪个 module 下的 res/values/dimens.xml 文件作为基准 dimens.xml 文件,生成的其他尺寸 dimens.xml 文件放在哪个 module 下。例如选择 app,然后点击 OK ,出现如下界面表示生成文件成功。如下图:
然后再看看 res 目录下会自动生成一堆 dimens.xml 文件,如下图:
通过上面的步骤就已经生成了所有设备对应的 dimens.xml 文件。
步骤 3 是以插件默认的最小宽度基准值为 360dp,适配的设备最小宽度为
320,360,384,392.7272,400,410,411.4285,432,480,533,592,600,640,662,720,768,800,811,820,960,961,1024,1280,1365(包含了平板和 TV )生成的文件,但实际情况要根据设计图和需求设置。
例如设计图的最小宽度为 375dp,则需要更改最小宽度基准值为 375dp。如果项目只需要适配手机的话,适配的设备最小宽度保留 320,360,384,392.7272,400,410,411.4285,432,480 即可,若发现手机还有其他最小宽度自行加上即可,也麻烦把该最小宽度提供给我,我们一起来完善该份适配。
以上修改需要在配置文件里修改,即 screenMatch.properties 文件,该配置文件是执行完上面第 3 步后自动生成在项目的跟目录下的。如下图:
打开配置文件,修改下图中 1、3、4 的值即可。(图中单位均为 dp)
1:最小宽度基准值,填写设计图的最小宽度值即可。
2:插件默认适配的最小宽度值,即默认情况下会生成如下值的 dimens.xml 文件。
3:需要适配的最小宽度值(如果是小数,则保留 4 位小数。例如 392.727272...,则取 392.7272),即你想生成哪些 dimens.xml 文件。
4:忽略不需要适配的最小宽度值,即忽略掉插件默认生成的 dimens.xml 文件。
配置文件修改完成后,重新执行第 3 步,生成新的 dimens.xml 文件。
当然!如果你的设计图也是标准的 360dp,那么上面的步骤你可以忽略。直接复制我 github 上你需要的 dimens.xml 文件到你的项目即可, 默认的 values 文件夹下也需要一份 。
设计图标注多少 dp,布局中就写多少 dp ,非常方便!
大多数 UI 设计师提供的设计图无非就几种,它们对应的使用方式如下:
说了这么多,其实只需要简单的 2 步:
很多人肯定会有疑问,难道我用了这套适配方案就可以全部直接写死宽高了?那肯定不是的,如果一些好用的适配技巧能实现的,那就不要用直接写死宽高的方式。这套适配方案搭配下面这些适配技巧可以让你的屏幕适配更完美。
绝对布局(AbsoluteLayout)直接使用 X、Y 坐标来控制控件的位置,对于屏幕碎片化这么严重的今天,使用绝对布局对于屏幕适配来说就是灾难性的,所以 Google 已经废弃了该控件。
相对布局(RelativeLayout)或者约束布局(ConstraintLayout)就不一样了,相对布局的子控件之间使用 相对位置 的方式排列,即使屏幕的大小改变,控件的相对位置也不会变化,与屏幕大小无关,灵活性很强。约束布局也是类似的,通过对某些控件进行约束来确定它们之间的位置。
Nine-Patch 图片是一种被特殊处理过的 PNG 图片,你可以指定哪些区域可以拉伸而哪些区域不可以。例如聊天界面中的聊天气泡背景图就需要做成 Nine-Patch 图片,因为每条消息的字数不是固定的,如果背景图片不能随着字数的长短进行缩放,那么就会导致背景图片变形。
因为各种屏幕高宽比并不是固定的,有 16:9、4:3,还有全面屏的 19.5:9 等等,如果强行将宽高都适配那只会导致布局变形。
例如一个控件的宽高为 360dp 和 640dp,如果将它显示在宽高为 360dp 和 640dp 的设备上是正常铺满整个屏幕的,但是显示在宽高为 360dp 和 780dp 的设备上高度则不能铺满,如果你让高度铺满,而宽度又保持不变,那就会出现变形的情况。所以这也就是为什么目前市面上的屏幕适配方案只能以宽或高一个维度去适配,另一个方向用滑动或权重的方式去适配的原因。
那你为什么说高度也能适配呢?
这里说的高度也能适配指的是在不同分辨率和密度的手机上能达到等比缩放的适配,其他屏幕适配方案也是一样的。
注意:smallestWidth 限定符适配的效果是让不同分辨率和密度的设备上能达到以设计图等比缩放的适配,如果设备与设计图相差太大时并不能达到很好的适配效果,需要单独出图,其他屏幕适配方案也是一样的。
同横屏道理一样,平板、TV 与手机的宽高差距太大,想要平板、TV 也能完全适配,那就只能让设计师出一套平板、TV 的设计图,然后单独写一套平板、TV 的布局文件。
注意:再说一遍,smallestWidth 限定符适配的效果是让不同分辨率和密度的设备上能达到以设计图等比缩放的适配,如果设备与设计图相差太大时并不能达到很好的适配效果,需要单独出图,其他屏幕适配方案也是一样的。
github 地址: ScreenAdaptation
参考资料:
Q4: Android-屏幕适配全攻略(绝对详细)(一)
关键字: 屏幕适配 px dp dpi sp large限定符 .9.png
前言: 这篇文章依然是我在 [慕课网 ][h]学习 凯子哥 的同名视频 Android-屏幕适配全攻略 ,所记录下来的笔记---凯子哥讲得真的超详细。
[h]: "MOOC"
从上图可以看出,主流的分辨率是前六种:1280×720、1920×1080、800×480、854×480、960×540、1184×720,不过我们有解决方案。看完这篇文章,想必你就可以解决常见的屏幕适配问题。
接下来正式进入正题。
介绍几个在Android屏幕适配上非常重要的名词:
屏幕尺寸 是指屏幕对角线的长度。单位是英寸,1英寸=2.54厘米
屏幕分辨率 是指在横纵向上的像素点数,单位是px,1px=1像素点,一般是纵向像素横向像素,如1280×720
屏幕像素密度 是指每英寸上的像素点数,单位是dpi,即“dot per inch”的缩写,像素密度和屏幕尺寸和屏幕分辨率有关
dip: Density Independent Pixels(密度无关像素)的缩写。以 160dpi 为基准,1dp=1px
dp: 同 dip
dpi: 屏幕像素密度的单位,“dot per inch”的缩写
px: 像素,物理上的绝对单位
sp: Scale-Independent Pixels的缩写,可以根据文字大小首选项自动进行缩放。Google推荐我们使用12sp以上的大小,通常可以使用12sp,14sp,18sp,22sp,最好不要使用奇数和小数。
用于区分不同的像素密度。
在Google官方开发文档中,说明了 ** mdpi:hdpi:xhdpi:xxhdpi:xxxhdpi=2:3:4:6:8 ** 的尺寸比例进行缩放。例如,一个图标的大小为48×48dp,表示在mdpi上,实际大小为48×48px,在hdpi像素密度上,实际尺寸为mdpi上的1.5倍,即72×72px,以此类推。
我们可以通过以下几种方式来支持各种屏幕尺寸:
wrap_content: 根据控件的内容设置控件的尺寸
math_parent: 根据父控件的尺寸大小设置控件的尺寸
weight: 权重,在线性布局中可以使用weight属性设置控件所占的比例
例如,我们要实现下图所显示的效果:当屏幕尺寸改变时,new reader控件两边的控件大小不变,new reader控件会占完剩余的空间。
具体布局文件如下:
小插曲: 关于 android:layout_weight 属性
一般情况,我们都是设置要进行比例分配的方向的宽度为0dp,然后再用权重进行分配。如下:
效果为:
效果为:
button1宽度=L+(L-2L)×1/3=2/3L
button2宽度=L+(L-2L)×2/3=1/3L
当然,还有其他的方式,都可以运用此公式进行计算。
在实际开发中,我们一般使用0dp的方式,而不使用其他方式。
简单的布局一般都使用 线性布局 ,而略微复杂点的布局,我们使用 相对布局 ,大多数时候,我们都是使用这两种布局的嵌套。
我们使用 相对布局 的原因是, 相对布局 能在各种尺寸的屏幕上保持控件间的相对位置。
res/layout/main.xml 单面板:
res/layout-large/main.xml 双面板:
如果这个程序运行在屏幕尺寸大于7inch的设备上,系统就会加载 res/layout-large/main.xml 而不是 res/layout/main.xml ,在小于7inch的设备上就会加载 res/layout/main.xml 。
需要注意的是,这种通过 large 限定符分辨屏幕尺寸的方法,适用于android3.2之前。在android3.2之后,为了更精确地分辨屏幕尺寸大小,Google推出了最小宽度限定符。
res/layout-sw600dp/main.xml ,双面板布局: Small Width 最小宽度
这种方式是不区分屏幕方向的。这种最小宽度限定符适用于android3.2之后,所以如果要适配android全部的版本,就要使用 large 限定符和 sw600dp 文件同时存在于项目 res 目录下。
这就要求我们维护两个相同功能的文件。为了避免繁琐操作,我们就要使用布局别名。
由于后两个文具文件一样,我们可以用以下两个文件代替上面三个布局文件:
res/layout/main.xml 单面板布局
res/layout/main_twopanes.xml 双面板布局
然后在 res 下建立
res/values/layout.xml 、
res/values-large/layout.xml 、
res/values-sw600dp/layout.xml 三个文件。
默认布局
res/values/layout.xml :
Android3.2之前的平板布局
res/values-large/layout.xml :
Android3.2之后的平板布局
res/values-sw600dp/layout.xml :
这样就有了 main 为别名的布局。
在activity中 setContentView(R.layout.main);
这样,程序在运行时,就会检测手机的屏幕大小,如果是平板设备就会加载 res/layout/main_twopanes.xml ,如果是手机设备,就会加载 res/layout/main.xml 。我们就解决了只使用一个布局文件来适配android3.2前后的所有平板设备。
如果我们要求给横屏、竖屏显示的布局不一样。就可以使用 屏幕方向限定符 来实现。
例如,要在平板上实现横竖屏显示不用的布局,可以用以下方式实现。
res/values-sw600dp-land/layouts.xml :横屏
res/values-sw600dp-port/layouts.xml :竖屏
自动拉伸位图,即android下特有的 .9.png 图片格式。
当我们需要使图片在拉伸后还能保持一定的显示效果,比如,不能使图片中的重要像素拉伸,不能使内容区域受到拉伸的影响,我们就可以使用 .9.png 图来实现。
要使用 .9.png ,必须先得创建 .9.png 图片,androidSDK给我们提供了的工具就包含 .9.png 文件的创建和修改工具。双击 SDK安装目录 oolsdraw9patch.bat ,就会打开下图所示的窗口。
下面是一个例子:
Button属性设置:
如果我们选择的内容区域偏差太大,可能就不会显示出text值 BUTTON 。
好了,这篇文章写的有点多了,剩下的内容放在 下篇文章 记录吧。
内容提要:
解决方案-支持各种屏幕密度
解决方案-实施自适应用户界面流程
未完待续
Q5: Android 屏幕适配
1: dp: android 尺寸的基本单位。 在不同的分辨率的手机里面,1dp对应着不同数量的px, 这样就实现了dp定义一个控件大小的时候,在不同分辨率手机里表现出相应大小的像素值。
2: 屏幕分辨率: 1080下160, 表示宽度有1080个像素点而高度有2160个像素点。常见的分辨率有320x480, 480x800, 720x1280, 1080x1920等。
3: 屏幕尺寸: 以寸为单位, Android设备对角线的长度
4: 像素密度: 每英寸的像素点
5: 屏幕尺寸, 分辨率,像素密度 三者之间的关系:
密度(dpi)= √(宽2 + 高2)/屏幕尺寸
6: px:像素,是屏幕上显示数据的最基本的点
7: dpi:屏幕像素密度,每英寸上的像素点数
8: sp:与dp类似,通常用于指定字体的大小,当用户修改手机显示的字体时,字体大小会随之改变。
1: dp适配方案: Android自带的原始的适配方案, 在不同的分辨率手机里面表现出相应大小的像素点。
缺点: Android的碎片化严重, 如果生产厂家没有根据屏幕尺寸、分辨率和像素密度的关系来规则定义, 或者出一些乱七八糟的屏幕大小,这样的适配方案就不在适合了。
2: 宽高限定符:枚举所有的屏幕宽高像素值,根据等比缩放去适配。如果没有找到对应的屏幕, 则取默认的。 目前这种方案已经被弃用。
缺点:
1: 占用资源大,会增加APK的体积。
2: 容错机制大需要精准命中资源文件才能适配,比如1920x1080的手机就一定要找到1920x1080的限定符,否则就只能用统一的默认的dimens文件了。而使用默认的尺寸的话,UI就很可能变形。
3:AndroidAutoLayout适配方案(停止维护)
4: SW限定符适配方案:(smallestWidth最小宽度适配)
Android 会去识别屏幕可用高度或者宽度的最小尺寸的dp值。然后根据识别到的结果去对应的资源文件里面去找寻相应的结果。
如何生成:ScreenMatch插件
此方案跟宽高限定的适配方案相比,有很好的容错机制, 如果没有找到对应的适配宽度, 那么会在vlues文件里面去找跟他最接近的宽度。
5:今日头条适配方案:
1: px 转 dp 的公式 dp = px / density.不管我们设定的单位是什么, 最终我们都会将这些单位长度转化为px的。density就是他们的转化比, 所以,动态改变这个转化比也是可以达到我们适配屏幕的目的的。
2: 通过修改density值,强行把所有不同尺寸分辨率的手机的宽度dp值改成一个统一的值(在清单文件中定义),这样就解决了所有的适配问题。
3: Density = 当前设备屏幕总宽度(单位为像素)/ 设计图总宽度(单位为 dp) ;
4:引入了AndroidAutoSize屏幕适配框架:
最后, 最重要的................
点赞 点赞 点赞, 不重要的事情也就说3遍......








