项目屏幕适配

一. 为什么要屏幕适配;
2012年到2014年支持Android设备的种类从3997增长到18796。同时各大厂商定制的屏幕尺寸也非常多。这将非常不利于我们进行屏幕适配。这要求我们必须掌握屏幕适配技能,以便使我们的app可以适用于不同屏幕尺寸的设备上。
二。屏幕尺寸
屏幕尺寸指屏幕的对角线的长度,单位是英寸,1英寸=2.54厘米
比如常见的屏幕尺寸有2.4、2.8、3.5、3.7、4.2、5.0、5.5、6.0等
屏幕分辨率
屏幕分辨率是指在横纵向上的像素点数,单位是px,1px=1个像素点。一般以纵向像素*横向像素,如1960*1080。

以谷歌的标准,按 安卓屏幕宽度为例,一般来说480px对应的density是1.5(也就是hdpi)对应320dp,720px对应的density是2.0(也就是xhdpi)对应360dp,1080px对应的density是3.0(也就是xxhdpi)对应360dp;
如果非要拿屏幕ppi说事的话,就是这样,以160ppi为基准,160ppi对应的density是1.0,240ppi对应的density是1.5,320ppi对应的density是2.0…
这些术语都是指屏幕的分辨率。
VGA:Video Graphics Array,即:显示绘图矩阵,相当于640×480 像素;
HVGA:Half-size VGA,即:VGA的一半,分辨率为480×320,像三星盖世Ace S5830就是使用这分辨率;
QVGA:Quarter VGA,即:VGA的四分之一,分辨率为320×240,一般用于小屏手机 像三星盖世Mini S5570就是使用这分辨率;
WQVGA:Wide Quarter VGA,即:扩大的QVGA,分辨率比QVGA高,比VGA低,一般是:400×240,480×272;
WVGA:Wide Video Graphics Array,即:扩大的VGA,分辨率为800×480像素,像三星i9000就是使用这分辨率;
FWVGA:Full Wide VGA ,数码产品屏幕材质的一种,VGA的另一种形式,比WVGA分辨率高,别名 : Full Wide VGA, ,其分辨 率为854×480象素(16:9)。


以下是一些常见的分辨率
标屏
分辨率
宽屏
分辨率
QVGA
320×240
WQVGA
400×240
VGA
640×480
WVGA
800×480
SVGA
800×600
WSVGA
1024×600
XGA
1024×768
WXGA
1280×768/1280×800/1280*960
SXGA
1280×1024
WXGA+
1440×900
SXGA+
1400×1050
WSXGA+
1680×1050
UXGA
1600×1200
WUXGA
1920×1200
QXGA
2048×1536
WQXGA
2560×1536


VGA
640*480 (Video Graphics Array)
-
QVGA
320*240 (Quarter VGA)
-
HVGA
480*320 (Half-size VGA)
mdpi
SVGA
800*600 (Super VGA)
-
5:3
尺寸
对应分辨率
WVGA
800*480 (Wide VGA)
hdpi
16:9
尺寸
对应分辨率
FWVGA
854*480 (Full Wide VGA)
hdpi
HD
1920*1080 High Definition
-
QHD
960*540
hdpi
720p
1280*720
xhdpi
1080p
1920*1080
xxhdpi
屏幕像素密度
屏幕像素密度是指每英寸上的像素点数,单位是dpi,即“dot per inch”的缩写。屏幕像素密度与屏幕尺寸和屏幕分辨率有关,在单一变化条件下,屏幕尺寸越小、分辨率越高,像素密度越大,反之越小。
dp、dip、dpi、sp、px


1.px (pixels)像素 – 是像素,就是屏幕上实际的像素点单位。

 dip或dp (device independent pixels)设备独立像素, 与设备屏幕有关(密度无关像素)。
理解一下密度无关像素:
480*320
160dpi (1px=1dp)
800*480
240dpi (1px=??dp)

dp = px * (dpi/160);

 sp (scaled pixels — best for text size):类似dp, 主要处理字体的大小。
dpi(dot per inch):屏幕像素密度,每英寸多少像素
density:density表示每英寸有多少个像素点(逻辑值),它的单位是dpi
DPI的计算: 对角屏幕像素点数/屏幕尺寸(4.95);
dpi=445
Nexus 5(1920*1080)

不同像素密度区分

1.2 分辨率对应DPI
"HVGA    mdpi"
"WVGA   hdpi "
"FWVGA hdpi "
"QHD      hdpi "
"720P     xhdpi"
"1080P   xxhdpi "
Android design

屏幕适配在么写:
1。wrap_content match-parent
weight (原有宽度+剩余空间占的百分比)
2/3L=L+(L-2L)*1/3L

2。使用相对布局,禁止使用相对布局或者写死值
3。使用限定符 (large)
使用最小宽度限定符,
使用布局别名,
使用屏幕方向限定符
4。使用自动拉伸图片
百分比适配
Percent Support Lib



有条理的整理
1. 什么是屏幕尺寸、屏幕分辨率、屏幕像素密度?
屏幕尺寸是指屏幕对角线的长度。单位是英寸,1英寸=2.54厘米
屏幕分辨率是指在横纵向上的像素点数,单位是px,1px=1像素点,一般是纵向像素横向像素,如1280×720
屏幕像素密度(dpi)是指每英寸上的像素点数,单位是dpi,即“dot per inch”的缩写,像素密度和屏幕尺寸和屏幕分辨率有关

屏幕像素密度计算公式

例如:计算Nexus5的屏幕像素密度:
屏幕尺寸:4.95inch、分辨率:1920×1080,屏幕像素密度:445


和官方给出的一样,说明我们计算正确。
2. 什么是dp、dip、dpi、sp、px?之间的关系是什么?
dip:Density Independent Pixels(密度无关像素)的缩写。以 160dpi为基准,1dp=1px
dp:dip
dpi:屏幕像素密度的单位,“dot per inch”的缩写
px:像素,物理上的绝对单位
sp:Scale-Independent Pixels的缩写,可以根据文字大小首选项自动进行缩放。Google推荐我们使用12sp以上的大小,通常可以使用12sp,14sp,18sp,22sp,最好不要使用奇数和小数。

dp的特点

说明:如果A设备的参数为480×320,160dpi,B设置的参数为800×480,240dpi。我们要画出一条和屏幕宽度一样长的直线,如果使用 px作为单位,必须在A设备上设置为320px,在B设备上设置480px。但是如果我们使用 dp作为单位,由于 以160dpi为基准,1dp=1px,所以A设备上设置为320dp就等于屏幕宽度(320px),在B设备上设置为320dp就等于320×(240/160)=480px,即B设备的屏幕宽度。这样,使用 dp作为单位就可以实现简单的屏幕适配。这知识一种巧合,也有B设备的像素密度不是这样刚刚好的,就需要我们运用别的屏幕适配技术。
3. 什么是mdpi、hdpi、xdpi、xxdpi、xxxdpi?如何计算和区分?
用于区分不同的像素密度。
名称
像素密度范围
图片大小
mdpi
120dp~160dp
48×48px
hdpi
160dp~240dp
72×72px
xhdpi
240dp~320dp
96×96px
xxhdpi
320dp~480dp
144×144px
xxxhdpi
480dp~640dp
192×192px

devices_displays_density@2x.png

在Google官方开发文档中,说明了 mdpi:hdpi:xhdpi:xxhdpi:xxxhdpi=2:3:4:6:8 的尺寸比例进行缩放。例如,一个图标的大小为48×48dp,表示在mdpi上,实际大小为48×48px,在hdpi像素密度上,实际尺寸为mdpi上的1.5倍,即72×72px,以此类推。
二. 解决方案-支持各种屏幕尺寸
我们可以通过以下几种方式来支持各种屏幕尺寸:
1. 使用wrap_content、math_parent、weight
wrap_content:根据控件的内容设置控件的尺寸
math_parent:根据父控件的尺寸大小设置控件的尺寸
weight:权重,在线性布局中可以使用weight属性设置控件所占的比例
例如,我们要实现下图所显示的效果:当屏幕尺寸改变时,new reader控件两边的控件大小不变,new reader控件会占完剩余的空间。


实现:通过给new reader控件设置属性: android:layout_width="wrap_content"android:layout_weight="1",两边两个控件为固定大小, android:layout_weight="0"
具体布局文件如下:
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal"> <TextView android:layout_width="80dp" android:layout_height="80dp" android:layout_weight="0" android:background="#028330"/> <TextView android:layout_width="wrap_content" android:layout_height="80dp" android:text="newreader" android:textSize="22sp" android:layout_weight="1"/> <TextView android:layout_width="160dp" android:layout_height="80dp" android:text="Politics" android:textSize="18sp" android:layout_weight="0" android:background="#028330"/></LinearLayout>
小插曲:关于 android:layout_weight属性
公式:所占宽度=原来宽度+剩余空间所占百分比的宽度
一般情况,我们都是设置要进行比例分配的方向的宽度为0dp,然后再用权重进行分配。如下:
<Button android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="Button1" /><Button android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="2" android:text="Button2" />
效果为:

宽度为0dp时,所占比例

设屏幕宽度为L,
根据公式,
button1宽度=0+L×1/(1+2)=1/3L
button2宽度=0+L×2/(1+2)=2/3L
但如果设置为 match_parent
<Button android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" android:text="Button1" /><Button android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="2" android:text="Button2" />
效果为:

宽度为match_parent时,所占比例
button1宽度=L+(L-2L)×1/3=2/3L
button2宽度=L+(L-2L)×2/3=1/3L
当然,还有其他的方式,都可以运用此公式进行计算。
在实际开发中,我们一般使用0dp的方式,而不使用其他方式。
2. 使用相对布局,禁用绝对布局
简单的布局一般都使用 线性布局,而略微复杂点的布局,我们使用 相对布局,大多数时候,我们都是使用这两种布局的嵌套。
我们使用 相对布局的原因是, 相对布局能在各种尺寸的屏幕上保持控件间的相对位置。
3. 使用限定符
  • 使用尺寸限定符
当我们要在大屏幕上显示不同的布局,就要使用 large限定符。例如,在宽的屏幕左边显示列表右边显示列表项的详细信息,在一般宽度的屏幕只显示列表,不显示列表项的详细信息,我们就可以使用 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-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>
如果这个程序运行在屏幕尺寸大于7inch的设备上,系统就会加载 res/layout-large/main.xml 而不是 res/layout/main.xml,在小于7inch的设备上就会加载 res/layout/main.xml
需要注意的是,这种通过 large限定符分辨屏幕尺寸的方法,适用于android3.2之前。在android3.2之后,为了更精确地分辨屏幕尺寸大小,Google推出了最小宽度限定符。
  • 使用最小宽度限定符
最小宽度限定符的使用和 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,双面板布局: Small Width 最小宽度
<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>
这种方式是不区分屏幕方向的。这种最小宽度限定符适用于android3.2之后,所以如果要适配android全部的版本,就要使用 large限定符和 sw600dp文件同时存在于项目 res目录下。
这就要求我们维护两个相同功能的文件。为了避免繁琐操作,我们就要使用布局别名。
  • 使用布局别名
res/layout/main.xml: 单面板布局
res/layout-large/main.xml: 多面板布局
res/layout-sw600dp/main.xml: 多面板布局
由于后两个文具文件一样,我们可以用以下两个文件代替上面三个布局文件:
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:
<resources> <item name="main" type="layout">@layout/main</item></resources>
Android3.2之前的平板布局
res/values-large/layout.xml:
<resources> <item name="main" type="layout">@layout/main_twopanes</item></resources>
Android3.2之后的平板布局
res/values-sw600dp/layout.xml:
<resources> <item name="main" type="layout">@layout/main_twopanes</item></resources>
这样就有了 main为别名的布局。
在activity中 setContentView(R.layout.main);
这样,程序在运行时,就会检测手机的屏幕大小,如果是平板设备就会加载 res/layout/main_twopanes.xml,如果是手机设备,就会加载 res/layout/main.xml 。我们就解决了只使用一个布局文件来适配android3.2前后的所有平板设备。
  • 使用屏幕方向限定符
如果我们要求给横屏、竖屏显示的布局不一样。就可以使用 屏幕方向限定符来实现。
例如,要在平板上实现横竖屏显示不用的布局,可以用以下方式实现。
res/values-sw600dp-land/layouts.xml:横屏
<resources> <item name="main" type="layout">@layout/main_twopanes</item></resources>
res/values-sw600dp-port/layouts.xml:竖屏
<resources> <item name="main" type="layout">@layout/main</item></resources>
4. 使用自动拉伸位图
自动拉伸位图,即android下特有的 .9.png图片格式。
当我们需要使图片在拉伸后还能保持一定的显示效果,比如,不能使图片中的重要像素拉伸,不能使内容区域受到拉伸的影响,我们就可以使用 .9.png图来实现。

AutoLayout 屏幕适配:







  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值