1.密度(density)
①屏幕密度的计算
手机像素密度(density)实际上是以单位英寸160个像素作为参考标准,主要密度有0.75,1,1.5,2和3,当密度为2时就表示1英寸有320个像素,Android中通过代码可以获取到屏幕的像素值和密度,根据这些值就
可以反向算出屏幕的物理尺寸:屏幕尺寸 = 屏幕对角线的像素值 / (密度*160) = [(长的平方+宽的平方)开根号] / (密度*160) --> dp = px / (density / 160)
简单来说:屏幕密度(density) = 对角线的像素值(px) / 屏幕大小(inch)
比如现在的htc one,屏幕分辨率1920*1080,屏幕大小4.7inch(英寸),对应的密度为:Math.sqrt(1920*1920+1080*1080) / 4.7 = 468.7<480,是xhdpi
②密度分类
低密度(120) ldpi : low-density --- QVGA和WQVGA
中密度(160) mdpi : medium-density --- HVGA Android的屏幕密度是以160为基准的,此时:1dp=1px
高密度(240) hdpi : high-density --- WVGA
超高密度(320) xhdpi : extra-high-density
极高密度(480) xxhdpi : extra-extra-high-density
③密度直观比较图
这是最新的官网设备密度截图,从图中可知:以MDPI(160)为标准参考值1,HDPI,XHDPI,XXHDPI分别为1.5,2,3。UI设计时,也可以此为参考,如设计一个中等密度(medium)屏幕的图标大小为48×48像素,
由low:medium:high:extra high:extra extra high = 3:4:6:8:12,这样的比值关系,得出:低密度(low)屏幕的图片大小应为36×36像素,高密度(high)屏幕的为72×72像素,超高密度(extra high)屏幕为
96×96像素,极高密度(extra-extra-high)屏幕为144×144像素。
由上图可知之前的低密度的LDPI(0.75x)没有出现在图中,取而代之的是XXHDPI,正所谓,长江后浪推前浪,前浪被拍死在沙滩上。。。
④各ui控件像素值
Icon Type
Standard Asset Sizes (in Pixels), for Generalized Screen Densities
Low density screen (ldpi)
Medium density screen (mdpi)
High density screen (hdpi)
Launcher
36 x 36 px
48 x 48 px
72 x 72 px
Menu
36 x 36 px
48 x 48 px
72 x 72 px
Status Bar
24 x 24 px
32 x 32 px
48 x 48 px
Tab
24 x 24 px
32 x 32 px
48 x 48 px
Dialog
24 x 24 px
32 x 32 px
48 x 48 px
List View
24 x 24 px
32 x 32 px
48 x 48 px
⑤代码中获取手机密度
public class TestPhoneDensity extends AndroidTestCase { public void testDensity() throws Exception { DisplayMetrics metric = new DisplayMetrics(); WindowManager wm = (WindowManager) getContext().getSystemService( Context.WINDOW_SERVICE); wm.getDefaultDisplay().getMetrics(metric); int densityDpi = metric.densityDpi; System.out.println("densityDpi:" + densityDpi); } }获取设备详细信息
DisplayMetrics metric = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(metric); int width = metric.widthPixels; // 屏幕宽度(像素) int height = metric.heightPixels; // 屏幕高度(像素) float density = metric.density; // 屏幕密度(0.75/1.0/1.5/2.0/3.0) int densityDpi = metric.densityDpi; // 屏幕密度DPI(120/160/240/320/480) double diagonalPixels = Math.sqrt(Math.pow(width, 2) + Math.pow(height, 2)); // 屏幕对角线长度(像素) double screenSize = diagonalPixels / (160 * density); // 屏幕尺寸 System.out.println("宽:"+width+", 高:"+height+", 密度:"+density+"("+densityDpi+")"+"\n"+"对角线像素值:"+diagonalPixels+", 屏幕大小:"+screenSize+"英寸");2.屏幕尺寸和密度
3.适配多种屏幕
①在manifest清单文件里定义程序支持的屏幕类型,相应代码如下:
<supports-screens android:resizeable=["true"| "false"] android:smallScreens=["true" | "false"] //是否支持小屏 android:normalScreens=["true" | "false"] //是否支持中屏 android:largeScreens=["true" | "false"] //是否支持大屏 android:xlargeScreens=["true" | "false"] //是否支持超大屏 android:anyDensity=["true" | "false"] //是否支持多种不同密度的屏幕 android:requiresSmallestWidthDp=”integer” android:compatibleWidthLimitDp=”integer” android:largestWidthLimitDp=”integer”/> <supports-screens android:smallScreens="true" android:normalScreens="true" android:largeScreens="true" android:xlargeScreens="true" android:anyDensity="true" android:resizeable="true"/>②对不同大小的屏幕提供不同的drawable,layout,values
res/drawable/my_drawable.png //默认res/drawable-ldpi/my_drawable.pngres/drawable-mdpi/my_drawable.pngres/drawable-land-mdpi/my_drawable.png //横向res/drawable-hdpi/my_drawable.pngres/drawable-xhdpi/my_drawable.pngres/drawable-xhhdpi/my_drawable.pngres/drawable-nodpi/my_drawable.png //平板res/drawable-hdpi-800x480/my_drawable.png //给指定分辨率做适配res/drawable-hdpi-854x480/my_drawable.pngres/drawable-sw600dp-mdpi/my_drawable.pngres/drawable-sw600dp-hdpi/my_drawable.pngres/drawable-sw600dp-xdpi/my_drawable.pngres/drawable-sw600dp-nodpi/my_drawable.png
res/layout/my_layout.xml //默认(放一些通用布局xml文件,比如界面中顶部和底部的布局,不会随着屏幕大小变化)res/layout-land/my_layout.xmlres/layout-port/my_layout.xmlres/layout-ldpi/my_layout.xmlres/layout-mdpi/my_layout.xmlres/layout-hdpi/my_layout.xmlres/layout-land-ldpi/my_layout.xmlres/layout-land-mdpi/my_layout.xmlres/layout-land-hdpi/my_layout.xmlres/layout-small/my_layout.xml //屏幕尺寸小于3英寸左右的布局res/layout-normal/my_layout.xml //屏幕尺寸小于4.5英寸左右res/layout-large/my_layout.xml //4英寸-7英寸之间res/layout-xlarge/my_layout.xml //7-10英寸之间res/layout-xlarge-land/my_layout.xml //横屏res/layout-sw600dp/my_layout.xml //sw<N>dp表示这个layout文件夹下面的布局文件只有在设备短边的最小宽为N时才加载~smallestWidthres/layout-sw600dp-port/my_layout.xml //竖屏下最小为600的宽度res/layout-w600dp/my_layout.xml //固定为600的宽度res/layout-sw720dp/my_layout.xml
res/values/dimens.xml //默认res/values-lhdpi/dimens.xmlres/values-mdpi/dimens.xmlres/values-hdpi/dimens.xmlres/values-xhdpi/dimens.xmlres/values-xhhdpi/dimens.xmlres/values-sw600dp/dimens.xml //同上res/values-sw720dp/dimens.xmlres/values-nodpi-1280x800/dimens.xml //1280x800分辨率的平板(nodpi用于存放不管宿主屏幕密度如何都不进行缩放的资源)res/values-large-land/dimens.xml //横向res/values-large-port/dimens.xml //竖直方向
从以上文件夹名称不难发现规律:
一类是根据dpi屏幕密度划分(ldpi,mdpi,hdpi,xhdpi,xxhdpi,nodpi),一类是根据屏幕尺寸划分(small,normal,large,xlarge,1280x800-可自定义尺寸,sw<N>dp),这两类中又可细分成横屏和竖屏。
对于根据dpi屏幕密度划分的横竖屏:xxx-land-ldpi,对于根据屏幕尺寸划分的横竖屏:xxx-small-land,另外较为复杂的:密度和尺寸混用:xxx-sw600dp-hdpi
-----------更新,看了官网的文档,才发觉以上的总结不过是冰山一角,以下是完整版
MCC and MNCExamples:mcc310,mcc310-mnc004,mcc208-mnc00.etc.Language and regionExamples:en,fr,en-rUS,fr-rFR,fr-rCA.etc.Layout Directionldrtl,ldltrsmallestWidthsw<N>dp,Examples:sw320dp,sw600dp,sw720dp.etc.Available widthw<N>dp,Examples:w720dp,w1024dp.etc.Available heighth<N>dp,Examples:h720dp,h1024dp.etc.Screen sizesmall,normal,large,xlargeScreen aspectlong,notlongScreen orientationport,landUI modecar,desk,television,applianceNight modenight,notnightScreen pixel density (dpi)ldpi,mdpi,hdpi,xhdpi,nodpi,tvdpiTouchscreen typenotouch,fingerKeyboard availabilitykeysexposed,keyshidden,keyssoftPrimary text input methodnokeys,qwerty,12keyNavigation key availabilitynavexposed,navhiddenPrimary non-touch navigation methodnonav,dpad,trackball,wheelPlatform Version (API level)Examples:v3,v4,v7.etc.
4.固定显示方向
在activity节点或是application节点下配置以下参数,表示屏幕方向固定为竖直方向或是横向,不随着传感器的变化而比变化。
android:screenOrientation="portrait" //竖直方向
android:screenOrientation="landscape" //横向
android:screenOrientation="sensor" //表示屏幕随着重力感应的方向变化而变化<即使重力感应没有开启>
5.Android各种屏幕分辨率(VGA、HVGA、QVGA、WQVGA、WVGA、FWVGA)
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
Low density (120), ldpiMedium density (160), mdpiHigh density (240), hdpiExtra high density (320), xhdpiSmallscreenQVGA (240x320) 480x640 NormalscreenWQVGA400 (240x400)WQVGA432 (240x432)HVGA (320x480)WVGA800 (480x800) WVGA854 (480x854) 600x1024640x960LargescreenWVGA800** (480x800) WVGA854** (480x854)WVGA800* (480x800) WVGA854* (480x854) 600x1024 Extra Largescreen1024x600WXGA (1280x800)†1024x7681280x7681536x11521920x1152 1920x12002048x15362560x1536 2560x1600
6.代码中写控件并设置宽高
①首先获取当前屏幕的宽高度,因为屏幕的宽高使用频率较高,且一般为不变常量,所以可以定义常量类保存当前屏幕的宽高 public class Constant { public static int DISPLAY_WIDTH; //屏幕宽度 public static int DISPLAY_HEIGHT; //屏幕高度 }在第一个Activity启动的时候,获取这两个值
DisplayMetrics displayMetrics = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(displayMetrics); Constant.DISPLAY_WIDTH = displayMetrics.widthPixels; Constant.DISPLAY_HEIGHT = displayMetrics.heightPixels;在代码中根据屏幕的宽高动态的设置控件的宽高
LayoutParams blueParams = new LayoutParams( (int) (Constant.DISPLAY_WIDTH * 0.2f + 0.5f), (int) (Constant.DISPLAY_HEIGHT * 0.2f + 0.5f)); bt_blue.setLayoutParams(blueParams); bt_blue.setBackgroundResource(R.color.blue); LayoutParams purpleParams = new LayoutParams( (int) (Constant.DISPLAY_WIDTH * 0.4f + 0.5f), (int) (Constant.DISPLAY_HEIGHT * 0.2f + 0.5f)); bt_purple.setLayoutParams(purpleParams); bt_purple.setBackgroundResource(R.color.purple); LayoutParams greenParams = new LayoutParams( (int) (Constant.DISPLAY_WIDTH * 0.6f + 0.5f), (int) (Constant.DISPLAY_HEIGHT * 0.2f + 0.5f)); bt_green.setLayoutParams(greenParams); bt_green.setBackgroundResource(R.color.green); LayoutParams orangeParams = new LayoutParams( (int) (Constant.DISPLAY_WIDTH * 0.8f + 0.5f), (int) (Constant.DISPLAY_HEIGHT * 0.2f + 0.5f)); bt_orange.setLayoutParams(orangeParams); bt_orange.setBackgroundResource(R.color.orange); LayoutParams redParams = new LayoutParams( (int) (Constant.DISPLAY_WIDTH * 1.0f + 0.5f), (int) (Constant.DISPLAY_HEIGHT * 0.2f + 0.5f)); bt_red.setLayoutParams(redParams); bt_red.setBackgroundResource(R.color.red);7.译文
http://developer.android.com/training/multiscreen/screensizes.html
中文翻译:http://bbs.9ria.com/thread-191031-1-1.html
8.Supporting Different Screen Sizes
①Use "wrap_content" and "match_parent"
②Use RelativeLayout
③Use Size Qualifiers
④Use the Smallest-width Qualifier
⑤Use Layout Aliases
⑥Use Orientation Qualifiers
⑦Use Nine-patch Bitmaps
http://developer.android.com/training/multiscreen/screensizes.html
参考资源
http://www.jb51.net/article/33238.htm
http://www.androidlearner.net/android-multi-screen-about.html (android – 多屏幕适配相关)
http://www.cnblogs.com/melaniedeng/archive/2012/05/17/2506869.html (Android系统如何实现UI的自适应 --> 资源文件framework调用链)
http://blog.csdn.net/lucherr/article/details/8498400 (Android各种屏幕分辨率(VGA、HVGA、QVGA、WQVGA、WVGA、FWVGA) 详解)
http://www.cnblogs.com/mybkn/articles/2535519.html (android:屏幕自适应)
http://blog.csdn.net/moruite/article/details/6028547 (Android手机分辨率基础知识(DPI,DIP计算))
http://developer.android.com/guide/practices/screens_support.html
http://developer.android.com/guide/topics/resources/providing-resources.html
转载于:https://www.cnblogs.com/wipedata/p/3169252.html