重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
从2017年开始,全面屏之战逐渐如火如荼的展开了,那么我们Android程序员又多了一个小事情,就是解决全面屏适配的问题。
宁阳ssl适用于网站、小程序/APP、API接口等需要进行数据传输应用场景,ssl证书未来市场广阔!成为创新互联公司的ssl证书销售渠道,可以享受市场价格4-6折优惠!如果有意向欢迎电话联系或者加微信:18982081108(备注:SSL证书合作)期待与您的合作!
全面屏和以前的屏幕相比,有以下几点改变
声明方式
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主题
在主题的样式中设置:
即可。
频繁的手机更新迭代,虽然让我们程序员多了一些事情可做,但是却也是我们喜闻乐见的事,手机在发展,说明我们的行业也在发展呀,况且,解决这些问题也不是难事。你说是不是呢?
如果没看懂我的文章,请观看小米官网提供的方案(其实是一致的):
全面屏及虚拟键适配说明
分辨率对应DPI
ldpi QVGA (240×320)
mdpi HVGA (320×480)
hdpi WVGA (480×800),FWVGA (480×854)
xhdpi 720P(1280*720)
xxhdpi 1080p(1920*1080 )
xxxhdpi 4K(3840×2160)
机型适配方面常规处理方法:
1、开发之前UI给出不同尺寸标准的多套素材,一般情况下给出:hdpi、xhdpi、xxxhdpi 三种尺寸类型的素材。
2、特殊类型图片使用Android Studio内置draw9path工具进行制作,例如聊天界面中内容背景图片。
3、布局编写时尽量使用 Linearlayout 与 RelativeLayout,LinearLayout内部可以使用weight(权重)属性将子控件的尺寸按比例进行设置。RelativeLayout 内部可以使用layout_align...(相对于xxx)属性将子控件的尺寸相对于父控件或相对于其他子控件进行设置。
4、设置尺寸的时候长度单位 布局使用 dp 字符使用 sp。 其实字体大小的尺寸使用 dp 也可以,但是sp的情况下 用户使用系统设置字体大小的时候可以改变控件中字体的大小,但是使用dp设置的字体就不会产生变化。
5、针对每一个屏幕的尺寸生成一套px与dp的转换方案,详情见博客: Android机型适配方案 。
6、google推出了一个百分比布局库,可以使用百分比的方式进行布局尺寸的设置,详情见博客: Android百分比布局库(percent-support-lib)解析与扩展
7、利用自定义View的方式去解决,其实原理也是,在绘制View的时候,获取屏幕的尺寸然后按照一定的比例去设置控件的尺寸
还有一些琐碎知识点需要了解并记住:
1. px (pixels)像素 :
一个像素通常被视为图像的最小的完整采样,这个用的比较多,特别是web开发,页面基本都是使用像素作为单位的.
2.dp:
这个是最常用但也最难理解的尺寸单位。它与“像素密度”密切相关,所以首先我们解释一下什么是像素密度。假设有一部手机,屏幕的物理尺寸为1.5英寸x2英寸,屏幕分辨率为240x320,则我们可以计算出在这部手机的屏幕上,每英寸包含的像素点的数量为240/1.5=160dpi(横向)或320/2=160dpi(纵向),160dpi就是这部手机的像素密度,像素密度的单位dpi是Dots Per Inch的缩写,即每英寸像素数量。横向和纵向的这个值都是相同的,原因是大部分手机屏幕使用正方形的像素点。
不同的手机/平板可能具有不同的像素密度,例如同为4寸手机,有480x320分辨率的也有800x480分辨率的,前者的像素密度就比较低。Android系统定义了四种像素密度:低(120dpi)、中(160dpi)、高(240dpi)和超高(320dpi),它们对应的dp到px的系数分别为0.75、1、1.5和2,这个系数乘以dp长度就是像素数。例如界面上有一个长度为“80dp”的图片,那么它在240dpi的手机上实际显示为80x1.5=120px,在320dpi的手机上实际显示为80x2=160px。如果你拿这两部手机放在一起对比,会发现这个图片的物理尺寸“差不多”。
3.dip:
与dp完全相同,只是名字不同而已。在早期的Android版本里多使用dip,后来为了与sp统一就建议使用dp这个名字了。
4.sp:
与缩放无关的抽象像素(Scale-independent Pixel)。sp和dp很类似但唯一的区别是,Android系统允许用户自定义文字尺寸大小(小、正常、大、超大等等),当文字尺寸是“正常”时1sp=1dp=0.00625英寸,而当文字尺寸是“大”或“超大”时,1sp1dp=0.00625英寸。类似我们在windows里调整字体尺寸以后的效果——窗口大小不变,只有文字大小改变。
还有一些详细的情况需要了解,都在这个博客里: 点击进入
android设备碎片化严重,因此在实际开发的时候需要做屏幕适配
适配主要是在以下几个方面:
常见的布局适配主要是以下几点:
a.避免写死布局尺寸,使用wrap_content或者martch_parent
b.使用权重,比如linearlayout中的weight;
c.使用relative的相对位置摆放,比如layout_centerInParent="true"
d.ConstraintLayout 原理类似于relatvie,相对摆放,但是性能相对于relatvie会好一点
e.android官方的库Percent-support-lib,该库主要是用的是百分比适配
a. .9图适配,这个是使用了.9图可以在特别区域拉伸不失真的特性来适配
b. 使用多套位图,匹配不同的分辨率,比如在mipmap,mipmap-xhdpi,mipmap-xxhdpi,等文件夹下面放多套分辨率不同的内容相同的图片
是指同一个业务逻辑,在不同的设备上执行不同的跳转方式,比如在手机上打开一个新的activity,但是在平板上,可以在横屏状态下,右侧增加一个fragment,展示打开的页面。
a.分辨率限定符,使用drawable-dpi,drawable-hdpi等
b.尺寸限定符
c.最小宽度限定符
d.屏幕方向限定符
a.android9.0开始 有官方的api进行适配
b.华为,小米,魅族,vivo,oppo各大room厂商有对应的api进行适配
除了以上这些,还有dimens适配,但是都各有缺点,有的需要多套图,有的需要多套资源文件,dimens适配的dimens文件过多,需要针对不同的屏幕分辨率来生成对应的文件,比较繁琐
以上,实际开发中,做的最多的适配为布局适配
开发中屏幕适配的核心是在于屏幕缩放,不论是哪种屏幕适配,都是以这个缩放为基础
已知:设计图手机像素(W,H),设计图上控件的像素值(ViewW,ViewH),目标设备分辨率(TargetW,TargetH)
求:目标设备上view的宽高(TargetViewW,TargetViewH)
公式:宽:ViewW / W * TargetW=TargetViewW
高:ViewH / H * TargetH =TargetViewH
原理:根据当前设备的分辨率,计算出设计图上的控件在该设备上的缩放比,然后根据缩放比,来动态的设置view, 最终换算出来的单位为px
该适配方式是通过自定义外部的ViewGroup,比如LinearLayout,RelativeLayout,在onMeasure方法中,遍历子view,设置宽高以及padding,margin
以下是封装了一个工具类,用来获取屏幕宽高以及计算缩放比:
未完待续
关键字: 屏幕适配 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 。
好了,这篇文章写的有点多了,剩下的内容放在 下篇文章 记录吧。
内容提要:
解决方案-支持各种屏幕密度
解决方案-实施自适应用户界面流程
未完待续
Android的屏幕大同小异,分辨率也是各种各样,手机App上的差异性还没那么明显,基本用Dp weight就可以比较好的适配各种手机。但是在Pad上的表现就不尽如意,而且发现像华为Pad Pro这种高端设备,是可以通过系统设置去设置修改系统的density值,导致整个如果只用一套DpUI布局去实现,会出现很奇怪的UI效果,基本不能适配。这时候就需要对UI进行适配。通过资料查询,需要了解如下的几个概念
1.px,pixel 就是像素,最基本的真实显示单位
2.dp,dip, Density-independent pixel,设备的独立像素,1dp表示在屏幕像素点密度为160ppi时1px长度
3.ppi, pixel per inch ,每英寸对角像素点,这个是物理上的
4.dpi, dot per inch ,每英寸多少个点,这个是软件上的,这里的点跟像素点不同
5.sp: scale-independent pixel, 字体大小单位
简单换算就是
ppi =根号( 横屏像素点平方+纵屏像素点平方)➗对角线的长度,这个长度是一英寸
1dp = (dpi/160) px
然后有些不同尺寸手机的ppi可能是420, 430, 440, 450, 460.,由于物理ppi上是固定的,改变不了,为了适配,通过人为设置一个dpi,来规范这些差不多ppi值,使得这些相差差不多的屏幕都是通用一个dpi,也就是使用同一套设计方案。
一开始通过dp值来实现适配,是可以解决大部分适配问题,但是在遇到pad这种设备,由于是横屏,而且系统设置还可以修改density值,使得用一套固定屏幕(比如1280 * 800)的方向变得不是那么合适。
这时候想到可以通过Android中 dimens中定义dimen值,Android中可以通过sw去搜索对应的dimen值表来获取对应的配置,smallestWidth适配,sw限定符适配,只要我们把对应的表通过换算,得到一个新值,就可以得到在不同的density值中得到对应的dp值表,解决华为上一个设备对应不同density值的问题。
那么问题来了,如果去得到sw不同的dimens呢,网上的方法很多,有些自己写脚本,有些自己写程序生成,为了就是列举所有的值,一般1-1000dp,然后基于一个基准,比如360dp宽度,去换算出不同屏幕宽度的dimens值,这里我推荐Android Studio的插件ScreenMatch,先安装插件
然后在values中创建dimens文件夹,并创建dimens.xml,其中写上自己定义的dp值,如下
然后在该文件右键,选择screenmatch
插件就会生成一堆其他屏幕的dimens文件,并且自动生成1-800的其他dp值,基本满足开发中的定义,如果没有的话,就自行在这里定义,然后重新生成。
关于ScreenMatch的生成还有一个基准,就是基于那个dpi来生成,通过插件生成,在根目录会多出了两个文件,一个example, 一个config文件
这里我们看看properties文件,内容如下
其中base_dp=850就是基于850,然后可以通过match_dp去调整要适配的dpi值。
通过这方方式,会在dimens文件自动生成dimen文件
在网上看到,还可以通过修改density去修改,这种方式有空我在试试