[转]android 屏幕适应的四个原则 +[转]android支持多尺寸屏幕【译】 mulit screen support
Best practices for Screen Independence
1. Prefer wrap_content, fill_parent and the dip unit to absolute pixels
When defining the layout_width and layout_height of views in an XML layout file, using wrap_content, fill_parent or the dip will guarantee that the view is given an appropriate size on the current device screen. For instance, a view with a layout_width=”100dip” will measure 100 pixels wide on an HVGA@160 density display and 150 pixels on a WVGA@240 density display, but the view will occupy approximately the same physical space.
Similarly, you should prefer the sp (scale-independent pixel, the scale factor depends on a user setting) or dip (if you don’t want to allow the user to scale the text) to define font sizes.
2. Avoid AbsoluteLayout
AbsoluteLayout is one of the layout containers offered by the Android UI toolkit. Unlike the other layouts however, AbsoluteLayout enforces the use of fixed positions which might easily lead to user interfaces that do not work well on different displays. Because of this, AbsoluteLayout was deprecated in Android 1.5 (API Level 3).
You can achieve much the same layout by using a FrameLayout instead, and setting layout_margin attributes of the children. This approach is more flexible and will yield better results on different screens.
3. Do not use hard-coded pixel values in your code
编码中定义的 数值默认都是pixel,所以不要写死。如果写死的要根据 屏幕的 density 值 做转换。
width = this.getWindowManager().getDefaultDisplay().getWidth();
float tempx = 94.0f / 320 * width;
For performance reasons and to keep the code simpler, the Android framework API uses pixels as the standard unit for expressing dimension or coordinate values. That means that the dimensions of a View are always expressed in the code in pixels. For instance, if myView.getWidth() returns 10, the view is 10 pixels wide. In some cases, you may need to scale the pixel values that you use in your code. The sections below provide more information.
Converting from dips to pixels
In some cases, you will need to express dimensions in dip and then convert them to pixels. Imagine an application in which a scroll gesture is recognized after the user’s finger has moved by at least 16 pixels. On a baseline screen, the user will have to move his finger by 16 pixels / 160 dpi = 1/10th of an inch (or 2.5 mm) before the gesture is recognized. On a device with a high (240) density display, the user will move his finger by only 16 pixels / 240 dpi = 1/15th of an inch (or 1.7 mm.) The distance is much shorter and the application thus appears more sensitive to the user. To fix this issue, the gesture threshold must be expressed in the code in dip and then converted to actual pixels.
// The gesture threshold expressed in dip
private static final float GESTURE_THRESHOLD_DIP = 16.0f;
// Convert the dips to pixels
final float scale = getContext().getResources().getDisplayMetrics().density;
mGestureThreshold = (int) (GESTURE_THRESHOLD_DIP * scale + 0.5f);
// Use mGestureThreshold as a distance in pixels
The android.util.DisplayMetrics.density field specifies the the scale factor you must use to convert dips to pixels according to the current screen density. You can access the current screen’s metrics through a Context or Activity. On a medium (160) density screen, DisplayMetrics.density equals “1.0″, whereas on a high (240) density screen it equals “1.5″. You can refer to the documentation of the DisplayMetrics class for details.
Use pre-scaled configuration values
The ViewConfiguration class can be used to access the most common distances, speeds, and times used in the Android framework. For instance, the distance in pixels used by the framework as the scroll threshold can be obtained as follows:
ViewConfiguration.get(aContext).getScaledTouchSlop()
Methods starting with the getScaled prefix are guaranteed to return a value in pixels that will display properly regardless of the current screen density.
4. Use density and/or size-specific resources
[转]android支持多尺寸屏幕【译】 mulit screen support
1. If your application is compiled for Android 1.5 or lower, Android will assume your application was designed to look good on the classic screen size and resolution.
android执行所谓的“兼容模式”
(a)对于大屏幕的,图片进行相应的放大,大小比例一致,但图片会因此而模糊;
(b)对更小屏幕,则直接提示不能运行
2. If your application is compiled for Android 1.6 or higher, Android assumes that you are properly handling all screen sizes, android执行所谓的“非兼容模式”,以下是一些应该掌握的技巧
(1)不要以具体位置,而以“规格或规则”来放置UI元素
Don't Think About Positions, Think About Rules
eg1. The simplest rules are the fill_parent and wrap_content values for android:layout_width and android:layout_height;eg2. The richest environment for easily specifying rules is to use RelativeLayout,
- Explicitly anchor widgets to the bottom or right side of the screen, rather than hoping they will wind up there courtesy of some other layout
- Control the distances between widgets that are "connected" (e.g., a label for a field should be to the left of the field) without having to rely on padding or margins
Consider Physical Dimensions
If you have something intrinsically scalable (e.g., a Button) where you had been specifying a size in pixels, you might consider switching to using millimeters (mm) or inches (in) as the unit of measure. 10mm is 10mm regardless of the screen resolution or the screen size. This way, you can ensure that your widget is sized to be finger-friendly, regardless of the number of pixels that might take.(3)避免以像素为单位(像素跟密度,分辨率对整体显示有印象)
Avoid "Real" Pixels
(a)使用dp或dip,优点是,在物理尺寸一致时,不同的密度值,对应的物理尺寸不变,即不依赖密度。即160dpi的机器上与240dpi的机器上50dip从视觉的大小上来讲是一样的。(b)对字体单位使用sp,系统会根据用户选择的字体大小对字体进行合理配比。
(4)选择可以伸缩的图片
Choose Scalable Drawables
选择九宫图( nine-patch bitmaps ),以及xml定义的图片(比如GradientDrawable),避免静态图片。3. 针对以上不能解决的问题,需要创建不同的资源集合
(a)Default集合,支持默认的拉伸,但拉伸算法会降低应用的执行速度;
(b)基于密度集合,创建分别以-ldpi, -mdpi, and -hdpi为后缀的资源集合,比如 res/values-hdpi/dimens.xml,是指适合hdpi设备的dimen.xml配置文件;
(c)基于尺寸集合,创建分别以-small, -normal, -large为后缀的资源集合,比如res/layout-large-land/,是指适合大屏幕(如WVGA)的横屏布局;
(d)基于版本集合,创建以-vN(N是对应版本的api级别)格式的资源集合,比如res/drawable-large-v4/,是指大屏幕,android 1.6版本或更新的文件夹。
4. 关于多分辨率多密度的android应用测试
由于基于LCD屏幕模拟器的密度一般比真机的密度小,布局方面的位置逻辑方面一致,但需要注意两个问题:
(i)真机下相同分辨率,物体会变得小很多;
(ii)使用触摸屏时,手指能点击的效果跟鼠标点击差别很大,前者在点击区域不大时,有时候很难点击上。
(a)1.6以上,特别是2.0以后模拟环境搭建测试,为了比较准确地模拟真机效果,可以选择AVD Manager,选中“Lauch Options”,选中"Scale display to real size",提供以下信息:
*模拟的机器的物理尺寸(inchs为单位)
**模拟器的dpi(可以点击右边的?获取)
但,由于基于LCD屏幕模拟器的密度一般比真机的密度小, 字体在真机下会比较失真,图片容易变得斑驳等。
(b)真机测试,可以购买代表性的几款手机(3款?),建立一个测试群,或者发布-反馈机制(用户反馈bug),或者加入deviceanywhere。参考:
http://www.androidguys.com/2010/02/16/handling-multiple-screen-sizes-part/
http://www.androidguys.com/2010/02/18/handling-multiple-screen-sizes-part-2/
http://www.androidguys.com/2010/02/23/handling-multiple-screen-sizes-part-3/
http://www.androidguys.com/2010/03/01/handling-multiple-screen-sizes-part-4/
http://www.androidguys.com/2010/03/02/handling-multiple-screen-sizes-part-5/
理解:
在线性布局中,采用 fill_parent来设置 子layout的高度 同时添加layout_weight属性,可以使界面按照理想的情况缩放,
如果采用wrap_content方法,缩放的比例很是奇怪,不利于控制
如果不设layout_weight属性,将会占据所能占据的空间,如果此时背景过大,可能占满整个屏幕,要注意
在AndroidManfest.xml中,如果不设置<uses-sdk android:minSdkVersion="8" /> 属性 就不能全屏
基于尺寸的集合 还没有试过,不知道是否可以设置单一的文件夹,使得代码自动选择对应的底图。

浙公网安备 33010602011771号