重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
前言:
成都创新互联公司专注于梅里斯网站建设服务及定制,我们拥有丰富的企业做网站经验。 热诚为您提供梅里斯营销型网站建设,梅里斯网站制作、梅里斯网页设计、梅里斯网站官网定制、成都微信小程序服务,打造梅里斯网络公司原创品牌,更为您提供梅里斯网站排名全网营销落地服务。
Android屏幕适配(1)基础知识篇
Android屏幕适配(2)常见:第一种
Android屏幕适配(3)常见:第二种
Android屏幕适配(5)常见:归纳总结
常见的屏幕配置问题(一些特殊的暂时除外,曲面屏,分屏模式,刘海屏),我归档为3种情况来分析一波
1.相同尺寸,不同分辨率屏幕
2.相同分辨率,不同尺寸屏幕
3.不同分辨率,不同尺寸屏幕
场景:
假设我们现在市面上的手机就只有oppo,vivo以下2款手机
其他的手机厂商和oppo,vivo的其他机型的手机全都洗白了
全世界的人都只有使用用这2款手机
一个oppo,300x400,5寸的手机,卖5000000RMB
一个vivo,600x800,5寸的手机,卖10000000RMB
我现在特别土豪,为了给大家写这篇帖子
我2个手机都买了
Android屏幕适配(2)常见:第一种
...
100年后,又有一个小米手机厂商出来了,发布了一款300x400,10寸的手机,10000000RMB
假设下图中里面的就是5000000RMB的oppo,外面的就是10000000RMB的小米
Android屏幕适配(3)常见:第二种
这时候我们
相同尺寸,不同分辨率屏幕
相同分辨率,不同尺寸屏幕
都解决了,然而这又有什么卵用?
告诉用户我们的APP只支持300x400分辨率的手机使用?
还是告诉用户我们的APP只支持5寸屏幕的手机使用?
第三种情况:不同分辨率,不同尺寸屏幕(任意手机)
只也是我们的终极目的,前面2篇适配只是做一个铺垫,让这里讲解的时候提到的东西更容易被理解
如果这里分析的还有未分析到的地方欢迎大家提出,一定及时修正
咱们还是先来个特殊的试试水,把300x400,5寸的同时放大2倍600x800,10寸
按惯性思维,这里同时放大2倍,肯定一张图片会自己也放大2倍,然后就适配了啊
使用PX
改用DP
GG了!三板斧劈完了!还是未能解决适配问题!!!
理性分析走一波:
1.PX不行的原因:(参考 Android屏幕适配(2)常见:第一种 )
PX是像素点单位,就是分辨率单位,不论屏幕尺寸怎么变只要分辨率没变,它所占的屏幕宽比都是一样的
也就是说当我们在使用PX的情况下,市面上的手机只要跟我们开发时候的分辨率是一样的都能适配
宽占比=图片宽PX/屏幕分辨率宽
分辨率改变
被除数不变,除数变,结果变=图片宽PX不变,屏幕分辨率宽变,结果变
所以这里的不同分辨率,不同尺寸屏幕情况是不满足分辨率相同原则的
所以这里的PX是不行的.
2.DP不行的原因:(参考 Android屏幕适配(3)常见:第三种 )
注:一下解释需要一些基础知识,建议先看 Android屏幕适配(1)基础知识篇 再往下看
无论我们开发中用什么虚拟单位(系统帮我们做了一次适配的单位),怎么个适配,最后显示在我们屏幕上都是以PX为单位的(构成图像的最小单位)
其实DP这个虚拟单位,最终显示的时候就是获取屏幕信息,再根据自身的算法规则,帮我们算出来的PX做为单位显示到屏幕上,但是它的算法已经是我们Android固定好了的(算法:规定以160dpi为基准,1dp=1dip=1px)
好,有了以上了解我们再回头来分析一下当前场景下的DP怎么就不行了
以上就是通过DP的固定算法换算PX的过程(PX=DP Desity=DP (DPI/160))
1.根据公式发现在同一DP宽度情况下改变PX值的唯一变量就是DPI了
2.结合以上计算过程,发现DPI都是100DPI,所以换算出来的PX肯定是相同的,也就是上图中的93.75PX
3.PX都相同了,那就又回到上面的PX不行的原因了!
所以这里的DP是不行的.
理性分析一波完不行的原因后,总该有点启发,或者思考方向吧!
整理归纳一下再看看有点启发没有-- 走起(我这里只知道PX跟DP,其他的一概不知道):
1.最终都是以PX显示到屏幕上
2.Android有一套适配置算法:DP,但是不能全部适配各种情况
3.我如果在开发的时候使用PX呢.结果如何? 那肯定就是死敲敲了.已经写死了,再也无法适配了.果断舍弃
4.有一点肯定的认知,在开发的时候我不能用死单位,还是需要使用虚拟单位,再生成PX的时候能生成我心中想要的PX就好了
5.那我到底需要在什么情况下生成多少PX呢?我也不知道,还是先把这个搞明白了来
就上面这种情况.我想达到的效果是怎么样的?
5.1占屏宽比在2个屏幕上都要是一样的,也就是说在300x400,5寸上75PX图片需要在600x800,10寸上是75PX,占屏宽比都要达到25%,见下图
对的,这就是我心中的蓝图了!
再回到上面DP不能适配的情况看看
这里的600x800,10寸上也就是说,占屏宽比也能达到:31.25%,跟300x400,5寸上一样就行了
此时的占屏宽比:31.25%就是图片PX要达到187.5PX
我:开发者
你:屏幕
这种情况下.我想做屏幕适配,其实就是我要来巴结你的节奏啊!
你说:我告诉你啊.开发者,在我这里其他的我都不认识,我只认识PX.你拿一个187.5PX的图片来.我立马适配,其他的都不用谈了!
我说:大哥你看能不能通融通融.我实在是搞不定了,你给我把93.75PX转成187.5PX把,立马递上一根自己都舍不得抽的,原产巴西的大雪茄!
你说:不是我不想.我是做不到.我只负责显示PX.其他的撒都不清楚,给你指条名路.你去求我们领导Android系统
Android系统说:我给屏幕小弟显示的PX算法都是固定死了的PX=图片宽DP Desity, Desity=DPI 160,不会为你一个人开后门.大家都在这个基础上做开发.众生平等!...... 虽然算法是固定死了的.但是我不是要提供限定符(SW)给你们吗?就是为了解决你们开发者的这个问题而存在的
我说:好的.我去看看, 限定符(SW)(Android屏幕适配(1)基础知识篇 )
结合SW限定符计算得到:
300x400,5寸屏 的限定符SW=300PX/Desity=300PX/0.625=480
600x800,10寸屏 的限定符SW=600PX/Desity=600PX/0.625=960
所以就是SW480和SW960
下面使用Android官方给我们提供的插件ScreenMatch(具体使用详情百度一大堆.查一下就明白了)自动给我们生成SWXXX文件
最后:
有什么理解不到位地方欢迎指正,以上理解均来源与对一些基础知识概念的理解,未实操证实过!
这种适配基本能解决大多数问题.还有一些小部分的就要特殊处理了,除了这种适配.还有其他的,以后再补上
建议ScreenMatch还是用base_dp=360,这个值基本兼容大部分屏幕.具体可以拿几个现目前市面上的手机真是分辨率跟屏幕尺寸算一算.我这里的例子只是举的特殊了.像SW960这种基本都不存在的.再说说之前留下的问题
提问 : 你这个例子举得太特殊了如果是300x400,5寸跟500x800,5寸占比就不同了
答:自己算一下SW是多少.生成一个对应的SW就行了,其他的任意机型同理
关键字: 屏幕适配 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去修改,这种方式有空我在试试
@[TOC](文章目录)
hr style=" border:solid; width:100px; height:1px;" color=#000000 size=1"
# 前言
font color=#999AAA 使用工具Android studio,利用values文件下dimens.xml界面适配安卓屏幕/font
hr style=" border:solid; width:100px; height:1px;" color=#000000 size=1"
font color=#999AAA 提示:以下是本篇文章正文内容,下面案例可供参考
# 一、概念
1.屏幕分辨率单位是px,例如Android手机常见的分辨率:320x480px、480x800px、720x1280px、1080x1920px。
2.手机屏幕的密度:每英寸的像素点数,单位是dpi。
| 密度类型 |代表的分辨率(px)| 屏幕像素密度(dpi) | 1dp转换为px |
|:--------|:--------|:--------|:--------|
| 低密度(ldpi) |240x320|120|0.75|
| 中密度(mdpi) |320x480|160|1|
| 高密度(hdpi)|480x800|240| 1.5|
| 超高密度(xhdpi)|720x1280|320|2|
| 超超高密度(xxhdpi) |1080x1920|480|3|
3.由于android的机型屏幕大小品类太多了,有一些是不标准的,这时我们就需要单独去获取屏幕的分辨率和密度了。
# 二、获取屏幕的分辨率和密度
```java
DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
float density = displayMetrics.density;
int densityDpi = displayMetrics.densityDpi;
int width = displayMetrics.widthPixels;
int height = displayMetrics.heightPixels;
Log.e("123","密度:"+density+"---"+densityDpi);
Log.e("123","屏幕分辨率:"+width+"x"+height);
Log.e("123","安卓系统:"+android.os.Build.VERSION.RELEASE);
Log.e("123","手表型号:"+android.os.Build.PRODUCT);
```
# 三、SmallestWidth适配
**smallestWidth适配,或者叫sw限定符适配。指的是Android会识别屏幕可用高度和宽度的最小尺寸的dp值(其实就是手机的宽度值),然后根据识别到的结果去资源文件中寻找对应限定符的文件夹下的资源文件。**
**sw计算公式:sw = 屏幕宽度 / (dpi/160) 注:160是默认的**
**例如:屏幕宽度为1080px、480dpi 的sw = 1080/(480/160)**
# 四、生成 dimens 文件
1、 首先在 res 目录下新建各种尺寸的 values 文件 。文件名为:values-sw(你要适配屏幕的sw值)dp。
例如:
![code23]()
注意:values文件下也生成 dimens文件
**生成dimens值工具类**
1、先生成标准的值。//value = (i + 1) * 1;
2、再用生成其他的值。 //value = (i + 1) * 需要生成的sw值/标准的sw值;
例如:value = (i + 1) * 160 / 320;
```java
public static void genDimen() {
StringBuilder stringBuilder = new StringBuilder();
try {
double value;
for (int i = 0; i 500; i++) {
//value = (i + 1) * 1; //这里控制对应转换的值,如果是标准尺寸就一对一转换
//value = (i + 1) * 需要生成的sw值/标准的sw值; //这里控制对应转换的值
value = (i + 1) * 1
//value = (i + 1) * 160 / 320;
value = Math.round(value * 100) / 100;
//dp可改成sp
stringBuilder.append("dimen name=\"size_" + (i + 1) + "\"" + value + "dp/dimen\r\n");
}
if (stringBuilder.length() 4000) {
for (int i = 0; i stringBuilder.length(); i += 4000) {
if (i + 4000 stringBuilder.length())
Log.e("123", stringBuilder.substring(i, i + 4000));
else
Log.e("123", stringBuilder.substring(i, stringBuilder.length()));
}
} else {
Log.e("123", stringBuilder.toString());
}
} catch (Exception e) {
e.printStackTrace();
} finally {
}
}
```
示例:(我这是以sw320为适配的标准的,你们可改自己的标准)
1、sw320的样例
```java
resources
dimen name="dimen_1"1.0dp/dimen
dimen name="dimen_2"2.0dp/dimen
dimen name="dimen_3"3.0dp/dimen
dimen name="dimen_4"4.0dp/dimen
dimen name="dimen_5"5.0dp/dimen
dimen name="dimen_6"6.0dp/dimen
dimen name="dimen_7"7.0dp/dimen
dimen name="dimen_8"8.0dp/dimen
dimen name="dimen_9"9.0dp/dimen
dimen name="dimen_10"10.0dp/dimen
dimen name="size_1"1.0sp/dimen
dimen name="size_2"2.0sp/dimen
dimen name="size_3"3.0sp/dimen
dimen name="size_4"4.0sp/dimen
dimen name="size_5"5.0sp/dimen
dimen name="size_6"6.0sp/dimen
dimen name="size_7"7.0sp/dimen
dimen name="size_8"8.0sp/dimen
dimen name="size_9"9.0sp/dimen
dimen name="size_10"10.0sp/dimen
/resources
```
2、sw160的样例
```java
resources
dimen name="dimen_1"0.0dp/dimen
dimen name="dimen_2"1.0dp/dimen
dimen name="dimen_3"1.0dp/dimen
dimen name="dimen_4"2.0dp/dimen
dimen name="dimen_5"2.0dp/dimen
dimen name="dimen_6"3.0dp/dimen
dimen name="dimen_7"3.0dp/dimen
dimen name="dimen_8"4.0dp/dimen
dimen name="dimen_9"4.0dp/dimen
dimen name="dimen_10"5.0dp/dimen
dimen name="size_1"0.0sp/dimen
dimen name="size_2"1.0sp/dimen
dimen name="size_3"1.0sp/dimen
dimen name="size_4"2.0sp/dimen
dimen name="size_5"2.0sp/dimen
dimen name="size_6"3.0sp/dimen
dimen name="size_7"3.0sp/dimen
dimen name="size_8"4.0sp/dimen
dimen name="size_9"4.0sp/dimen
dimen name="size_10"5.0sp/dimen
/resources
```
3、xml界面控件使用样例
```java
TextView
android:layout_width="@dimen/dimen_30"
android:layout_height="@dimen/dimen_30"
android:textSize="@dimen/size_20"
android:layout_margin="@dimen/dimen_10"
android:padding="@dimen/dimen_10"
```
hr style=" border:solid; width:100px; height:1px;" color=#000000 size=1"
# 总结
font color=#999999 提示:这里对文章进行总结:
如果你的app需要适配dpi较低的屏幕,最好以最小dpi的sw为适配的标准。