Android屏幕适配

前言

Android运行在提供不同屏幕尺寸和密度的多种设备上。 对应用程序而言,Android系统提供一致的跨设备的开发环境并且处理适配不同显示屏幕的大部分工作。同时,系统提供API,允许针对不同的屏幕尺寸和密度来控制的应用程序UI,从而为不同的屏幕配置来优化UI设计。

尽管系统会进行缩放和调整,以使应用程序在不同的屏幕上运行,仍然应该尽量为不同的屏幕尺寸和密度来优化应用。最大限度的为所有设备优化用户体验,这样用户才会认为应用程序是真正的为他们的设备设计的,而不是简单的拉伸或缩放来适应他们的设备。

DP单位转换为屏幕像素是简单的:PX = DP *DPI / 160

要注意的Andr​​oid 3.2推出新的API,更精确地控制应用程序使用不同屏幕尺寸的布局资源。如果你正在开发为平板优化的应用程序,这些新功能尤其重要

· 广义的尺寸大小集合: small(小)normal(正常)large(大), and xlarge(超大)

:从Android 3.2API Level 13)开始,这种尺寸集合被废弃,取而代之的是一种基于可用屏幕宽度来管理屏幕尺寸的新技术。所以针对Android 3.2以及以上版本的开发,可以参考 Android 3.2设计平板布局来获取更多信息

为不同屏幕尺寸和密度优化应用程序的用户界面,可以提供任何广义的大小和密度的alternative resources(选择性资源)。通常情况下,应该为不同的屏幕尺寸提供alternative layouts并且为不同的屏幕密度提供alternative bitmap images。在运行时,系统基于当前设备的广义屏幕尺寸或密度为应用程序采用适当的资源,

不需要为每一个屏幕大小和密度的组合提供选择性资源。系统提供了强大的兼容特性,可以处理在任何设备的屏幕上呈现应用程序的大部分工作,开发者只要实现UI技术,允许它正常调整。

Android系统可以通过两种方式使应用程序实现密度独立:

· 系统缩放dp单位以适应当前屏幕密度

· 系统基于当前屏幕密度按需要缩放可曳资源到合适尺寸

在大多数情况下,可以简单的通过用密度无关像素(dp units)来定义所有的布局尺寸或者适当的通过"wrap_content"来确保应用程序密度无关。然后系统依据当前屏幕密度的比例因子按比例决定bitmap drawable以显示合适的尺寸。

然而,位图缩放可能会导致模糊或像素化的位图。为了避免这些人为效果,应该为不同密度提供选择性位图资源。例如,应该为高密度的屏幕提供更高分辨率的位图从而系统可以不必去调整为低密度屏幕准备的位图。以下部分描述如何为不同的屏幕配置提供选择性资源。

如何支持多屏幕

1. 在清单文件中明确声明应用程序支持的所有屏幕尺寸

通过声明应用程序支持的屏幕尺寸,可以保证只有那些屏幕尺寸被应用程序支持的设备才可以下载该应用程序。声明对不同屏幕尺寸的支持,也可以影响系统如何在更大的屏幕展现应用程序特别地,应用程序是否在屏幕兼容模式运行。声明应用程序支持的屏幕尺寸,应该在manifest文件中包括 <supports-screens>元素。

2.为不同的屏幕尺寸提供不同的布局

可以使用限定符来提供尺寸相关的资源,这些限定符包括smallnormallarge xlarge。例如,一个超大大屏幕的布局,应该在layout-xlarge/

Android 3.2API Level 13)开始,上述尺寸组已被弃用,应该使用sw<N>dp 限定符定义布局资源所需的最小可用宽度。例如,如果多窗格平板布局至少需要600dp屏幕的宽度,应该放置在layout-sw600dp/下。使用新技术来声明布局源在 Android 3.2设计平板布局部分有进一步讨论。

3.为不同的屏幕尺寸提供不同的bitmap drawable

如果应用程序只为基准,中型屏幕密度(MDPI)屏幕提供了bitmap drawable,那么系统将会在高密度屏幕上放大它们,而在低密度屏幕上缩小它们。这种缩放可能会让位图产生失真。 

为了让位图最好的展示,应该为不同屏幕密度提供不同分辨率的位图。


在运行时,系统为任何给定资源通过以下步骤来尽可能确保它们在当前屏幕的显示:

1. 系统使用适当的可选资源

`当前屏幕的大小和密度的基础上,系统使用应用程序提供的任意尺寸和密度相关资源。例如,设备有一个高密度的屏幕并且应用程序请求一个drawable 资源,系统会寻找一个最匹配设备配置的drawable 资源目录。与其它可选资源相比,以hdpi 为限定符的资源目录(比如drawable-hdpi/)会最佳匹配,所以系统使用该目录下的drawable资源。

2. 如果没有匹配的资源是可用的,系统将使用默认的资源并且对其进行缩放来适应当前的屏幕尺寸和密度。 

“默认”的资源是那些没有配置限定符的资源。例如,在drawable/ 下的就是是默认的资源。系统假定默认资源是为基线屏幕尺寸和密度而设计的。正因为如此,系统对其采取缩放是比较可取的。

3.然而,当系统试图寻找一个密度相关的资源但是在密度相关的目录下没有找到时,系统并不总是使用默认资源。系统可能会改用其他密度相关的资源之一,以提供更好的缩放结果。 例如,当寻找一个低密度资源而没找到时,系统倾向于缩小高密度资源,因为系统可以通过缩放因子0.5轻松地将高密度资源缩小为低密度,这种缩放要比通过缩放因子0.75将中密度资源缩小为低密度不易失真。

使用配置限定符

Android支持多种配置限定符,来控制系统如何根据当前设备屏幕的特点选择可选的资源。配置限定符是一个字符串,可以在Andr​​oid项目追加到资源目录,并指定配置资源的内部设计。

使用配置的限定符:

1. 在工程的res/目录下创建一个新的目录,并将其以如下格式命名:<resources_name>-<qualifier>

<resources_name> 是标准的资源名 (比如drawable 或者 layout).

<qualifier> 是一个配置限定符, 如下面的表1所示, 它限定了这些资源可以用于的屏幕配置(比如 hdpi 或者 xlarge).

可以一次使用多个 <qualifier> —使用破折号将多个限定符分开。

2. 在这个新目录保存适当的配置相关资源。资源文件命名务必与默认的资源文件命名一致。

比如xlarge 是一个超大屏幕的限定符。当追加此字符串到一个资源目录名(比如layout-xlarge),这就告诉系统这些资源是要用在拥有超大屏幕的设备上的。

注意,Android系统在运行时选择使用哪些资源时,它使用某些逻辑来决定“最佳匹配”的资源。也就是说,使用的限定符没有必要完全匹配当前的屏幕配置。具体来说,当基于尺寸限定符来选择资源时,如果没有更好的匹配,系统会选择使用为比当前屏幕小的屏幕设计的资源(例如,一个大屏如果需要,可能会使用正常屏的资源)。但是,如果只有比当前屏幕尺寸大的资源,那么系统将不会使用这些大的资源,应用程序将会因无从选择而崩溃。(例如,如果所有的资源都是xlarge 限定符的,但是设备是一个normal-size的设备)

如果有一些绘制资源,不想让系统进行缩放(也许是因为想要在程序运行时进行手动调整),应该将其放置nodpi 配置限定符的目录下。这个限定符的资源被视为密度无关,系统将不能扩展。

如果需要使用XML来定义形状,颜色或者可绘制的资源,应当在默认的drawable 目录备份一份

要创建不同密度的选择性的图片,应该在四个广义密度之间遵循3:4:6:8的缩放比例。比如,一个中密度下为48x48像素的位图(应用程序启动图标),与之对应的所有不同的尺寸应当是:

· 低密度为36x36 

· 中密度为48x48 

· 高密度为72x72 

· 超高密度为96x96 

Android 3.2设计平板布局

为了适应其他类型的平板电脑和屏幕尺寸,Android 3.2引入了一种新的为分散屏幕尺寸定义资源的方式。这种新技术是基于布局所需的空间数量(比如600dp宽),而不是试图让布局去符合广义的尺寸分类(比如大或者超大)。

使用新的尺寸限定符

见表2,这些新的限定符,比传统的屏幕尺寸分类(小,中,大,和超大)能提供更多的对于定义应用程序支持的屏幕的控制。

使用这​​些限定符指定的大小不是实际的屏幕尺寸。相反,是可以用于活动窗口的宽度或者高度尺寸,是以dp为单位的

系统会为系统UI使用一些屏幕空间(比如系统栏或者状态栏),所以一些屏幕空间对应用程序是不可用的。因此,声明的尺寸应当明确的是activity所需的尺寸当系统声明应当提供多少空间给布局时,它会计算任何被系统UI占据的空间。 同时注意, Action Bar被认为是应用程序的一部分空间,尽管布局没有声明它,因此它减少了可用的布局空间,你必须考虑在设计之内。


Table 2. 屏幕尺寸的新的配置限定符(在Android 3.2中引入)

Screen configuration

Qualifier values

Description

smallestWidth

sw<N>dp

Examples:
sw600dp
sw720dp

The fundamental size of a screen, as indicated by the shortest dimension of the available screen area. Specifically, the device's smallestWidth is the shortest of the screen's available height and width (you may also think of it as the "smallest possible width" for the screen). You can use this qualifier to ensure that, regardless of the screen's current orientation, your application's has at least <N> dps of width available for it UI.

For example, if your layout requires that its smallest dimension of screen area be at least 600 dp at all times, then you can use this qualifer to create the layout resources, res/layout-sw600dp/. The system will use these resources only when the smallest dimension of available screen is at least 600dp, regardless of whether the 600dp side is the user-perceived height or width. The smallestWidth is a fixed screen size characteristic of the device; the device's smallestWidth does not change when the screen's orientation changes.

The smallestWidth of a device takes into account screen decorations and system UI. For example, if the device has some persistent UI elements on the screen that account for space along the axis of the smallestWidth, the system declares the smallestWidth to be smaller than the actual screen size, because those are screen pixels not available for your UI.

This is an alternative to the generalized screen size qualifiers (small, normal, large, xlarge) that allows you to define a discrete number for the effective size available for your UI. Using smallestWidth to determine the general screen size is useful because width is often the driving factor in designing a layout. A UI will often scroll vertically, but have fairly hard constraints on the minimum space it needs horizontally. The available width is also the key factor in determining whether to use a one-pane layout for handsets or multi-pane layout for tablets. Thus, you likely care most about what the smallest possible width will be on each device.

Available screen width

w<N>dp

Examples:
w720dp
w1024dp

Specifies a minimum available width in dp units at which the resources should be used—defined by the <N> value. The system's corresponding value for the width changes when the screen's orientation switches between landscape and portrait to reflect the current actual width that's available for your UI.

This is often useful to determine whether to use a multi-pane layout, because even on a tablet device, you often won't want the same multi-pane layout for portrait orientation as you do for landscape. Thus, you can use this to specify the minimum width required for the layout, instead of using both the screen size and orientation qualifiers together.

Available screen height

h<N>dp

Examples:
h720dp
h1024dp
etc.

Specifies a minimum screen height in dp units at which the resources should be used—defined by the <N> value. The system's corresponding value for the height changes when the screen's orientation switches between landscape and portrait to reflect the current actual height that's available for your UI.

Using this to define the height required by your layout is useful in the same way as w<N>dp is for defining the required width, instead of using both the screen size and orientation qualifiers. However, most apps won't need this qualifier, considering that UIs often scroll vertically and are thus more flexible with how much height is available, whereas the width is more rigid.

虽然使用这些限定符可能看起来比使用屏幕尺寸分组似乎更复杂,一旦确定用户界面的要求,它实际上应该是更简单。当设计UI时,关心的主要事情是当应用程序在手机式UI和平板式UI之间迁移时它的实际尺寸。


配置实例

为了您针对不同类型的设备进行设计,这里是典型的屏幕宽度的一些数字:

· 320dp: 一个典型的手机屏幕 (240x320 ldpi, 320x480 mdpi, 480x800 hdpi, ).

· 480dp: Streak一样的中立平板屏幕 (480x800 mdpi).

· 600dp: 7”平板 (600x1024 mdpi).

· 720dp: 10”平板 (720x1280 mdpi, 800x1280 mdpi, ).

使用表2中的尺寸限定符,应用程​​可以使用任何您想要的宽度和/或高度为手机和平板之间切换不同的布局资源。比如,如果600dp是平板布局所支持的最小可用宽度,可以提供这两套布局:

res/layout/main_activity.xml           # For handsets
res/layout-sw600dp/main_activity.xml   # For tablets

在这种情况下,为了让平板布局实用,可用屏幕空间的最小宽度必须为600dp 

要进一步定制UI区分大小,如7“和10”平板的情况下,可以定义额外的最小宽度布局:

res/layout/main_activity.xml           # For handsets (smaller than 600dp available width)
res/layout-sw600dp/main_activity.xml   # For 7” tablets (600dp wide and bigger)
res/layout-sw720dp/main_activity.xml   # For 10” tablets (720dp wide and bigger)

注意,前面的两个例子资源使用“最小宽度”限定符,sw<N>dp,它指定屏幕两边的最小值,无论设备的当前方向。因此,使用sw<N>dp是简单的通过忽略屏幕方向的方式来指定布局的整体屏幕尺寸。

然而,在某些情况下,可能重要的是布局究竟有多大的宽度或高度目前是可用的。例如,有两个并排的布局,每当屏幕宽度至少提供600dp时使用,不论设备是否是在横向或纵向。在这种情况下,资源看起来像这样:

res/layout/main_activity.xml         # For handsets (smaller than 600dp available width)
res/layout-w600dp/main_activity.xml  # Multi-pane (any screen with 600dp available width or more)

请注意,第二组使用“可用宽度”限定符,w<N>dp。这样,一台设备可能根据屏幕的方向会使用这两种布局(如果可用宽度在一个方向至少600dp而在另一个方向小于600dp)。

如果关注的是可用高度,那么同样可以使用h<N>dp限定符。甚至可以结合使用w<N>dp  h<N>dp 限定符。

随着屏幕尺寸的新的配置限定符,Android 3.2引入了<supports-screens> 元素的新属性。

android:requiresSmallestWidthDp

指定的最低宽度。 smallestWidth是指必须提供给应用程序的UI最短尺寸的屏幕空间(单位dp),也就是说,最短的可用屏幕的两个维度。因此,为了让一个设备与应用程序兼容,设备的smallestWidth必须等于或大于这个值。 (通常情况下,该值是布局支持测“最小宽度”,无论当前屏幕的方向。)

例如,如果应用程序仅用于最小可用宽度是600dp的平板式设备:

<manifest ... >
    <supports-screens android:requiresSmallestWidthDp="600" />
    ...
</manifest>

不过,如果应用程序支持Andr​​oid支持的所有屏幕尺寸(如426dp x 320dp这么小),那么并不需要声明这个属性,因为应用程序需要的最小宽度在任何设备上都是最小的。

android:compatibleWidthLimitDp

这个属性允许通过指定应用程序支持的最大"smallest width"来让screen compatibility mode (屏幕兼容模式)成为用户可选的特性。如果设备的可用屏幕最小的一边大于该值,用户仍然可以安装该应用程序,但提供在屏幕兼容性模式运行。默认情况下,屏幕兼容模式是无效的,而且布局会去调整适应普通的屏幕,但是系统栏会提供一个按钮来允许用户切换屏幕兼容模式开关。

android:largestWidthLimitDp

这个属性允许通过指定应用程序支持的最大的"smallest width"来强制启用 screen compatibility mode屏幕兼容模式。如果设备的可用屏幕最小的一边大于该值,应用程序会强制运行在屏幕兼容模式,用户无法干预。

Android 3.2及以上版本开发时,不应该使用上面列出的属性结合旧的屏幕大小属性。同时使用新属性和旧属性,可能会导致意想不到的行为。

最佳实践

1. 当在XML布局文件中定义尺码时,使用 wrap_contentfill_parent或者 dp 单位 

2. 不要在应用程序代码中使用硬编码的像素值

3. 不要使用 AbsoluteLayout (它已被废弃)

4.  为不同的屏幕密度提供可选的位图

关于密度的额外思考

本节信息对于大多数的应用程序是不重要的,除非在不同屏幕密度上运行应用程序时遇到问题或者应用程序需要操作图像。

如果应用程序创建一个内存位图(Bitmap 对象),系统会假设该位图是专为基准密度屏幕设计的并且在绘制时进行自动缩放。系统当位图有不明密度属性时,将 “自动缩放”运用于一个Bitmap位图。如果没有正确地统计当前设备的屏幕密度,并指定位图的密度属性,自动缩放会导致缩放失真,就像没有提供可选性资源一样。

为了控制在运行时创建的位图是否被缩放,可以用setDensity()来指定位图的密度,通过传递一个来自DisplayMetrics的密度常量,比如DENSITY_HIGH 或者 DENSITY_LOW

如果使用BitmapFactory创建一个Bitmap ,如从一个文件或流,可以使用BitmapFactory.Options来定义位图属性,该属性决定了系统是否或者如何缩放位图。

dp单位转换为像素单位

在某些情况下,需要用dp 来表示尺寸,然后将它们转换为像素。想象一个应用程序,当用户手指移动至少16像素,则形成一个滚动或者抛掷手势。在基准屏幕上,用户必须在手势形成之前移动16个像素/ 160 dpi,等于一英寸的十分之一(2.5毫米)。在高密度显示器(240dpi)的设备上,用户必须移动16个像素/ 240 dpi,这等于一英寸的十五分之一(1.7毫米)。距离要短得多,因此,应用程序似乎对用户更加敏感。

为了解决这个问题,在代码中手势门槛必须用dp 来表示,然后转化为实际的像素。例如:

// The gesture threshold expressed in dp
private static final float GESTURE_THRESHOLD_DP = 16.0f;

// Get the screen's density scale
final float scale = getResources().getDisplayMetrics().density;
// Convert the dps to pixels, based on density scale
mGestureThreshold = (int) (GESTURE_THRESHOLD_DP * scale + 0.5f);

// Use mGestureThreshold as a distance in pixels...

 DisplayMetrics.density域指定缩放因子,使用该缩放因子根据当前的屏幕密度来把dp 转换为像素。在一个中等密度的屏幕上,DisplayMetrics.density等于1.0;在一个高密度的屏幕上,它等于1.5;在一个超高密度屏幕上,它等于2.0;在低密度屏幕上,它等于0.75。用dp乘以这个数字就得到当前屏幕的实际像素数值。 (当转换为整数时,添加0.5f 四舍五入到最接近的整数)


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
1. Introduction 1.1 Document Structure 1.1.1. Requirements by Device Type 1.1.2. Requirement ID 1.1.3. Requirement ID in Section 2 2. Device Types 2.1 Device Configurations 2.2. Handheld Requirements 2.2.1. Hardware 2.2.2. Multimedia 2.2.3. Software 2.2.4. Performance and Power 2.2.5. Security Model 2.3. Television Requirements 2.3.1. Hardware 2.3.2. Multimedia 2.3.3. Software 2.3.4. Performance and Power 2.4. Watch Requirements 2.4.1. Hardware 2.4.2. Multimedia 2.4.3. Software 2.4.4. Performance and Power 2.5. Automotive Requirements 2.5.1. Hardware 2.5.2. Multimedia 2.5.3. Software 2.5.4. Performance and Power 2.5.5. Security Model 2.6. Tablet Requirements 2.4.1. Hardware 3. Software 3.1. Managed API Compatibility 3.1.1. Android Extensions 3.1.2. Android Library 3.2. Soft API Compatibility 3.2.1. Permissions 3.2.2. Build Parameters 3.2.3. Intent Compatibility 3.2.3.1. Core Application Intents 3.2.3.2. Intent Resolution 3.2.3.3. Intent Namespaces 3.2.3.4. Broadcast Intents 3.2.3.5. Default App Settings 3.2.4. Activities on secondary displays 3.3. Native API Compatibility 3.3.1. Application Binary Interfaces 3.3.2. 32-bit ARM Native Code Compatibility 3.4. Web Compatibility 3.4.1. WebView Compatibility 3.4.2. Browser Compatibility 3.5. API Behavioral Compatibility 3.5.1. Background Restriction 3.6. API Namespaces 3.7. Runtime Compatibility 3.8. User Interface Compatibility 3.8.1. Launcher (Home Screen) 3.8.2. Widgets 3.8.3. Notifications 3.8.3.1. Presentation of Notifications 3.8.3.2. Notification Listener Service 3.8.3.3. DND (Do not Disturb) 3.8.4. Search 3.8.5. Alerts and Toasts 3.8.6. Themes 3.8.7. Live Wallpapers 3.8.8. Activity Switching 3.8.9. Input Management 3.8.10. Lock Screen Media Control 3.8.11. Screen savers (previously Dreams) 3.8.12. Location 3.8.13. Unicode and Font 3.8.14. Multi-windows 3.8.15. Display Cutout 3.9. Device Administration 3.9.1 Device Provisioning 3.9.1.1 Device owner provisioning 3.9.1.2 Managed profile provisioning 3.9.2 Managed Profile Support 3.9.3 Managed User Support 3.10. Accessibility 3.11. Text-to-Speech 3.12. TV Input Framework 3.13. Quick Settings 3.14. Media UI 3.15. Instant Apps 3.16. Companion Device Pairing 3.17. Heavyweight Apps 4. Application Packaging Compatibility 5. Multimedia Compatibility 5.1. Media Codecs 5.1.1. Audio Encoding 5.1.2. Audio Decoding 5.1.3. Audio Codecs Details 5.1.4. Image Encoding 5.1.5. Image Decoding 5.1.6. Image Codecs Details 5.1.7. Video Codecs 5.1.8. Video Codecs List 5.2. Video Encoding 5.2.1. H.263 5.2.2. H-264 5.2.3. VP8 5.2.4. VP9 5.3. Video Decoding 5.3.1. MPEG-2 5.3.2. H.263 5.3.3. MPEG-4 5.3.4. H.264 5.3.5. H.265 (HEVC) 5.3.6. VP8 5.3.7. VP9 5.4. Audio Recording 5.4.1. Raw Audio Capture 5.4.2. Capture for Voice Recognition 5.4.3. Capture for Rerouting of Playback 5.5. Audio Playback 5.5.1. Raw Audio Playback 5.5.2. Audio Effects 5.5.3. Audio Output Volume 5.6. Audio Latency 5.7. Network Protocols 5.8. Secure Media 5.9. Musical Instrument Digital Interface (MIDI) 5.10. Professional Audio 5.11. Capture for Unprocessed 6. Developer Tools and Options Compatibility 6.1. Developer Tools 6.2. Developer Options 7. Hardware Compatibility 7.1. Display and Graphics 7.1.1. Screen Configuration 7.1.1.1. Screen Size and Shape 7.1.1.2. Screen Aspect Ratio 7.1.1.3. Screen Density 7.1.2. Display Metrics

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值