android的屏幕适配一直是开发人员头疼的问题。由于android的设备大小不一,并且屏幕显示效果也不同样,怎样对android进行屏幕适配是一个非常大的挑战,为了应对不同的情况。须要细致研究android对不同屏幕的定义。看过学渣的这篇博客。希望大家对屏幕适配有一个主要的了解。
1 android的屏幕大小
android的屏幕有大有小,为了对不同大小屏幕的设备提供最好的体验。须要对不同大小的设备进行不同的设计,首先遇到的问题就是android对屏幕大小的区分。
android的屏幕问题在官网有具体说明,,作为一名学渣,须要细细研读。首先android把屏幕分为四种大小:small,normal,large,xlarge,这四种屏幕首先是直观的区分,即对设备的对角线用尺子量一下,用英寸做单位进行区分。比方学渣用的红米就是4.7英寸。属于normal,具体分类如图1所看到的:
图1 android屏幕大小区分
如果你的程序获知android设备屏幕后,依据大小不同能够採用不同的布局方案,可是我们敲代码时,进行布局时,不可能用英寸进行布局,先如果我们使用像素(px)进行布局。可是这里会遇到一个问题,这里须要介绍新的term,请看2。
。
。。。
2 屏幕的分辨率和密度
这里遇到的问题须要看几个术语,android官网上去后有几个术语介绍,学渣先为大家介绍分辨率和密度
分辨率(Resolution):The total number of physical pixels on a screen. 即一个设备的物理像素,如1280*720,大家能够自己计算。
密度(Screen density):The quantity of pixels within a physical area of the screen; usually referred to as dpi (dots per inch).一般我们的密度的单位是像素数目/平方英寸,可是这里推荐了一个新的密度表示方法,就是每英寸的像素数目(dpi)。我们以后用到的密度就是这个dpi。
android里用分辨率和密度这两个域来记录设备的真实尺寸,採用密度的主要原因(学渣猜的)应该是“去英寸化”。即在程序中不要出现英寸这个单位。因此用密度和分辨率这两个值能够保存设备的真实尺寸。
对于一个程序而言,它能够获取到屏幕的分辨率和尺寸,进而密度=分辨率/尺寸,能够算出尺寸,在android里,获取密度尺寸能够參考这里。我们这里用一个小程序来求两个设备的分辨率和密度。学渣定义了两台avd。尺寸都是4.7英寸,设备1的分辨率为800*1280,设备2的分辨率为480*800,測试代码例如以下:
package com.example.testscreen; import android.os.Bundle; import android.app.Activity; import android.util.DisplayMetrics; import android.view.Menu; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); DisplayMetrics metrics = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(metrics); //得到设备的分辨率,即宽和高的像素数目 int height = metrics.heightPixels; int width = metrics.widthPixels; System.out.println("the height is "+height +" the width is" + width); //得到设备的密度 int density = metrics.densityDpi; System.out.println("the density is " + density); } }
设备1的输出是:
06-09 00:10:17.188: I/System.out(2041): the height is 1184 the width is768 06-09 00:10:17.188: I/System.out(2041): the density is 320设备2的输出是:
06-09 00:45:35.085: I/System.out(2088): the height is 736 the width is480 06-09 00:45:35.085: I/System.out(2088): the density is 213
从两个设备的输出能够知道。事实上学渣是定义了两个4.7英寸的avd。可是有着不同的分辨率,(android里有底部栏。看起来有点不一样),这两个样例说明了一个问题:同样大小的手机,能够有不同的分辨率,进而就有不同的密度喽,(由于密度=分辨率/大小)。
3 程序推断屏幕大小
每一个程序都须要判定屏幕的大小,进而选择合适的布局(后面会说)。怎样判定大小(设备的真实尺寸,能够理解为设备对角线的英寸数)呢,就依据2所提到的两个參数来推断,一个是分辨率。一个是密度,用设备1而言,知道height是1184像素(px)。其密度为320dpi(像素/英寸),则高度的详细值就是1280/320=4(英寸)。宽度为800/320=2.5 ,用勾股定理算出对角线的长度,(学渣这里没有细算)再和图1匹配,得到这个设备的屏幕大小尺寸。
屏幕大小判定之后,首先须要在mainfest声明支持的屏幕大小,如:
<supports-screens android:largeScreens="true" />
要想要好的用户体验,程序能够依据不同的大小选择不同的布局,android官方文档里也提到了,能够对不同的大小。设置不同的layout,如res/layout-large就是large屏幕时所採用的布局。
官方文档里有这么几句话要注意:Beginning
with Android 3.2 (API level 13), the above size groups are deprecated and you should instead use the sw<N>dp
configuration
qualifier to define the smallest available width required by your layout resources. For example, if your multi-pane tablet layout requires at least 600dp of screen width, you should place it inlayout-sw600dp/
.即对于3.2以上的,直接採用dp(dp相当于一种程序中的英寸大小)进行推断屏幕的宽度。进而选择不同的布局,如/res/layout-sw600dp,就是宽度要求是600dp以上的我们就选择这个布局。
只是意思和small,large等一样,仅仅只是把大小换成了详细的数字。
3 去英寸化
上面我们提到了去英寸化。怎样让一个程序能够非常好的显示大小呢。似乎能够採用像素?可是这是全然不能够的。先举一个简单的样例说明像素的缺陷,还是採用上述的设备1和设备2进行測试,我们在设备1和设备2都定义一个button,宽度和高度都为200px(像素),效果如图2所看到的:
图2 同样大小的手机,同样的像素大小的button
事实上这个结果一点也不意外,这是由于两个button的像素大小尽管一样,可是密度不同。而最后的真实大小是依照英寸来画的,由于密度=像素/英寸,则 真实大小(英寸数)=像素/密度。
那么这个问题怎么破,由于我们的程序一定是在同样大小的屏幕上有同样的大小,假设两个空间的大小一样,则是其英寸数相等。而英寸数又不能直接写在程序里。于是乎出现一个逆天的术语,dp。事实上在2里我们看到过这个dp,那么什么是dp呢?
dp在官网里叫Density-independent pixel (dp),即密度无关的像素。即能够摆脱密度的缠绕。就是前面我所提到的一种具有“去英寸化”功能的新的单位。我们先不提dp的详细计算(后面会说),我们就先如果这个dp就是一个全新的度量单位,让相等的dp在不同密度的屏幕里有相等的长度,比方1dp不管你是在设备1还是设备2,大小都是相等。
这就是攻克了“去英寸化”的问题。
4 dp的应用与图片问题
通过3的描写叙述,我们应该能够知道,在layout里不论什么的控件都採用dp就能够保证显示一致的问题了。
这也是google所推荐的。
可是对于图片这样的外来户。我们能够规定它在layout中的大小,假如我们规定了图片的宽度1英寸(能够转为dp,后面会将)。对于一张图片。其真实的宽度为15像素。在密度为3dpi的屏幕中。能够显示3个像素,这时须要丢掉12个像素,图片一定极为不清晰;在密度为15dpi的屏幕里能够显示15个像素。显示全然。这就有了分辨率的问题,在宽度都为1英寸的情况下,肯定是能够显示所有15个像素的图片清晰,怎么能让不同密度的屏幕显示的照片都比較清晰呢,我们能够对不同密度的屏幕选择不同的图片,即高密度选择高清图片。
对于不论什么一张图片。我们都能够做三张,一张低分辨率,一张高分辨率。一张中间值,对于高密度的屏幕,比方密度为15。我们选择一张分辨率较高的图片(就是大的图片)。如15英寸的,对于密度为3的。我们让它显示一张分辨率为3的,则保证了不会丢失信息,从而保证图片清晰。
对于不同密度的屏幕,能够通过/res/drawable-hdpi等进行选择图片。
这个官网也有。
5 dp的计算
事实上我们不是必需对dp进行计算,可是为了便于理解,我还是把dp的计算说一下, px
= dp * (dpi / 160)
。
。
。
另外:android里字体的大小採用sp,详细的还没有研究,只是作用预计和dp几乎相同。
这篇博客花了学渣一个中午的时间,对于android的学习,学渣觉得应该以官网为主要參考。假设本文内容有误。欢迎指出,谢谢!