`
modabobo
  • 浏览: 507395 次
文章分类
社区版块
存档分类
最新评论

兼容不同的屏幕大小

 
阅读更多

由于Android设备的碎片特性,关于屏幕适配的话题一直绵绵不休,这篇文章是Android开发者官网的屏幕适配教程,算是非常官方的解决方案,我们可以从这里学到很多。


这节课教你如何通过以下几种方式支持多屏幕:

☞确保你的布局能自适应屏幕
根据你的屏幕配置提供合适的UI布局
确保你当前的布局适合当前的屏幕
提供合适的位图(bitmap)


1.使用“wrap_content”和“match_parent”

为了确保你的布局能灵活的适应不同的屏幕尺寸,针对一些view组件,你应该使用wrap_content和match_parent来设置他们的宽和高。如果你使用了wrap_content,view的宽和高会被设置为该view所包含的内容的大小值。如果是match_parent(在API 8之前是fill_parent)则被设置为该组件的父控件的大小。

通过使用wrap_content和match_parent尺寸值代替硬编码的尺寸,你的视图将分别只使用控件所需要的空间或者被拓展以填充所有有效的空间。比如:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <LinearLayout android:layout_width="match_parent"
                  android:id="@+id/linearLayout1"
                  android:gravity="center"
                  android:layout_height="50dp">
        <ImageView android:id="@+id/imageView1"
                   android:layout_height="wrap_content"
                   android:layout_width="wrap_content"
                   android:src="@drawable/logo"
                   android:paddingRight="30dp"
                   android:layout_gravity="left"
                   android:layout_weight="0" />
        <View android:layout_height="wrap_content"
              android:id="@+id/view1"
              android:layout_width="wrap_content"
              android:layout_weight="1" />
        <Button android:id="@+id/categorybutton"
                android:background="@drawable/button_bg"
                android:layout_height="match_parent"
                android:layout_weight="0"
                android:layout_width="120dp"
                style="@style/CategoryButtonStyle"/>
    </LinearLayout>

    <fragment android:id="@+id/headlines"
              android:layout_height="fill_parent"
              android:name="com.example.android.newsreader.HeadlinesFragment"
              android:layout_width="match_parent" />
</LinearLayout>
注意上面的例子使用wrap_content和match_parent来指定组件尺寸而不是使用固定的尺寸。这样就能使你的布局正确的适配不同的屏幕尺寸和屏幕配置(这里的配置主要是指屏幕的横竖屏切换)。

例如,下图演示的就是该布局在竖屏和横屏模式下的效果,注意组件的尺寸是自动适应宽和高的。


2.使用相对布局(RelativeLayout)

你可以使用LinearLayout以及wrap_content和match_parent组合来构建复杂的布局,但是LinearLayout却不允许你精准的控制它子view的关系,子view在LinearLayout中只能简单一个接一个的排成行。如果你需要你的子view不只是简简单单的排成行的排列,更好的方法是使用RelativeLayout,它允许你指定你布局中控件与控件之间的关系,比如,你可以指定一个子view在左边,另一个则在屏幕的右边。

  1. <?xmlversion="1.0"encoding="utf-8"?>
  2. <RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent">
  5. <TextView
  6. android:id="@+id/label"
  7. android:layout_width="match_parent"
  8. android:layout_height="wrap_content"
  9. android:text="Typehere:"/>
  10. <EditText
  11. android:id="@+id/entry"
  12. android:layout_width="match_parent"
  13. android:layout_height="wrap_content"
  14. android:layout_below="@id/label"/>
  15. <Button
  16. android:id="@+id/ok"
  17. android:layout_width="wrap_content"
  18. android:layout_height="wrap_content"
  19. android:layout_below="@id/entry"
  20. android:layout_alignParentRight="true"
  21. android:layout_marginLeft="10dp"
  22. android:text="OK"/>
  23. <Button
  24. android:layout_width="wrap_content"
  25. android:layout_height="wrap_content"
  26. android:layout_toLeftOf="@id/ok"
  27. android:layout_alignTop="@id/ok"
  28. android:text="Cancel"/>
  29. </RelativeLayout>

3.使用据尺寸限定词

这里的限定词只要是指在编写布局文件时,将布局文件放在加上类似large,sw600dp等这样限定词的文件夹中,以此来告诉系统根据屏幕选择对应的布局文件,比如下面例子的layout-large文件夹

我们知道如何编写灵活的布局或者相对布局,它们都能通过拉伸或者填充控件来适应不同的屏幕,但是它们却无法为每个不同屏幕尺寸提供最好的用户体验。因此,你的应用不应该只是实现灵活的布局,同时也应该为不同的屏幕配置提供几种不同的布局方式。你可以通过配置限定(configuration qualifiers)来做这件事情,它能在运行时根据你当前设备的配置(比如不同的屏幕尺寸设计了不同的布局)来选择合适的资源。

比如,很多应用都为大屏幕实现了“两个方框”模式(应用可能在一个方框中实现一个list,另外一个则实现list的content),平板和电视都是大到能在一个屏幕上适应两个方框,但是手机屏幕却只能单个显示。所以,如果你想实现这些布局,你就需要以下文件:

res/layout/main.xml.单个方框(默认)布局:

  1. <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
  2. android:orientation="vertical"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent">
  5. <fragmentandroid:id="@+id/headlines"
  6. android:layout_height="fill_parent"
  7. android:name="com.example.android.newsreader.HeadlinesFragment"
  8. android:layout_width="match_parent"/>
  9. </LinearLayout>

res/layout-large/main.xml,两个方框布局:

  1. <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
  2. android:layout_width="fill_parent"
  3. android:layout_height="fill_parent"
  4. android:orientation="horizontal">
  5. <fragmentandroid:id="@+id/headlines"
  6. android:layout_height="fill_parent"
  7. android:name="com.example.android.newsreader.HeadlinesFragment"
  8. android:layout_width="400dp"
  9. android:layout_marginRight="10dp"/>
  10. <fragmentandroid:id="@+id/article"
  11. android:layout_height="fill_parent"
  12. android:name="com.example.android.newsreader.ArticleFragment"
  13. android:layout_width="fill_parent"/>
  14. </LinearLayout>

注意第二个布局文件的目录名字“large qualifier”,在大尺寸的设备屏幕时(比如7寸平板或者其他大屏幕的设备)就会选择该布局文件,而其他比较小的设备则会选择没有限定词的另一个布局(也就是第一个布局文件)。


4.使用最小宽度限定词

在Android 3.2之前,开发者还有一个困难,那就是Android设备的“large”屏幕尺寸,其中包括Dell Streak(设备名称),老版Galaxy Tab和一般的7寸平板,有很多的应用都想针对这些不同的设备(比如5和7寸的设备)定义不同的布局,但是这些设备都被定义为了large尺寸屏幕。也是因为这个,所以Android在3.2的时候开始使用最小宽度限定词。

最小宽度限定词允许你根据设备的最小宽度(dp单位)来指定不同布局。比如,传统的7寸平板最小宽度为600dp,如果你希望你的UI能够在这样的屏幕上显示两个方框(一个方框的显示在小屏幕上),你可以使用上节中提到的同样的两个布局文件,不同的是,使用sw600来指定两个方框的布局使用在最小宽度为600dp的设备上。

res/layout/main.xml,单个方框(默认)布局:

  1. <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
  2. android:orientation="vertical"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent">
  5. <fragmentandroid:id="@+id/headlines"
  6. android:layout_height="fill_parent"
  7. android:name="com.example.android.newsreader.HeadlinesFragment"
  8. android:layout_width="match_parent"/>
  9. </LinearLayout>

res/layout-sw600dp/main.xml,两个方框布局:

  1. <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
  2. android:layout_width="fill_parent"
  3. android:layout_height="fill_parent"
  4. android:orientation="horizontal">
  5. <fragmentandroid:id="@+id/headlines"
  6. android:layout_height="fill_parent"
  7. android:name="com.example.android.newsreader.HeadlinesFragment"
  8. android:layout_width="400dp"
  9. android:layout_marginRight="10dp"/>
  10. <fragmentandroid:id="@+id/article"
  11. android:layout_height="fill_parent"
  12. android:name="com.example.android.newsreader.ArticleFragment"
  13. android:layout_width="fill_parent"/>
  14. </LinearLayout>

这样意味着当你的设备的最小宽度等于600dp或者更大时,系统选择layout-sw600dp/main.xml(两个方框)的布局,而小一点的屏幕则会选择layout/main.xml(单个方框)的布局。 然而,在3.2之前的设备上,这样做并不是很好的选择。因为3.2之前还没有将sw600dp作为一个限定词出现,所以,你还是需要使用large限定词来做。因此,你还是应该要有一个布局文件名为res/layout-large/main.xml,和res/layout-sw600dp/main.xml一样。在下一节中,你将学到如何避免像这样出现重复的布局文件。


5.使用布局别名

最小宽度限定词只能在android3.2或者更高的版本上使用。因此,你还是需要使用抽象尺寸(small,normal,large,xlarge)来兼容以前的版本。比如,你想要将你的UI设计为在手机上只显示一个方框的布局,而在7寸平板或电视,或者其他大屏幕设备上显示多个方框的布局,你可能得提供这些文件:

res/layout/main.xml:单个方框布局
res/layout-large:多个方框布局
res/layout-sw600dp:多个方框布局

最后两个文件都是一样的,因为其中一个将会适配Android3.2的设备,而另外一个则会适配其他Android低版本的平板或者电视。 为了避免这些重复的文件(维护让人感觉头痛就是因为这个),你可以使用别名文件。比如,你可以定义如下布局: res/layout/main.xml,单个方框布局 res/layout/main_twopans.xml,两个方框布局 然后添加这两个文件:

res/values-large/layout.xml:

  1. <resources>
  2. <itemname="main"type="layout">@layout/main_twopanes</item>
  3. </resources>

res/values-sw600dp/layout.xml:

  1. <resources>
  2. <itemname="main"type="layout">@layout/main_twopanes</item>
  3. </resources>

最后两个文件拥有相同的内容,但它们并没有真正意义上的定义布局。它们只是将main_twopanes设置成为了别名main,它们分别处在large和sw600dp选择器中,所以它们能适配Android任何版本的平板和电视(在3.2之前平板和电视可以直接匹配large,而3.2或者以上的则匹配sw600dp)。


6.使用方向限定词

有一些布局不管是在横向还是纵向的屏幕配置中都能显示的非常好,但是更多的时候,适当的调整一下会更好。在News Reader应用例子中,以下是布局在不同屏幕尺寸和方向的行为:

小屏幕,纵向:一个方框加logo 小屏幕,横向:一个方框加logo

7寸平板,纵向:一个方框加action bar

7寸平板,横向:两个宽方框加action bar

10寸平板,纵向:两个窄方框加action bar

10寸平板,横向:两个宽方框加action bar

电视,横向:两个宽方框加action bar

这些每个布局都会再res/layout目录下定义一个xml文件,如此,应用就能根据屏幕配置的变化根据别名匹配到对应的布局来适应屏幕。

res/layout/onpane.xml:

  1. <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
  2. android:orientation="vertical"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent">
  5. <fragmentandroid:id="@+id/headlines"
  6. android:layout_height="fill_parent"
  7. android:name="com.example.android.newsreader.HeadlinesFragment"
  8. android:layout_width="match_parent"/>
  9. </LinearLayout>

res/layout/onepane_with_bar.xml:

  1. <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
  2. android:orientation="vertical"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent">
  5. <LinearLayoutandroid:layout_width="match_parent"
  6. android:id="@+id/linearLayout1"
  7. android:gravity="center"
  8. android:layout_height="50dp">
  9. <ImageViewandroid:id="@+id/imageView1"
  10. android:layout_height="wrap_content"
  11. android:layout_width="wrap_content"
  12. android:src="@drawable/logo"
  13. android:paddingRight="30dp"
  14. android:layout_gravity="left"
  15. android:layout_weight="0"/>
  16. <Viewandroid:layout_height="wrap_content"
  17. android:id="@+id/view1"
  18. android:layout_width="wrap_content"
  19. android:layout_weight="1"/>
  20. <Buttonandroid:id="@+id/categorybutton"
  21. android:background="@drawable/button_bg"
  22. android:layout_height="match_parent"
  23. android:layout_weight="0"
  24. android:layout_width="120dp"
  25. style="@style/CategoryButtonStyle"/>
  26. </LinearLayout>
  27. <fragmentandroid:id="@+id/headlines"
  28. android:layout_height="fill_parent"
  29. android:name="com.example.android.newsreader.HeadlinesFragment"
  30. android:layout_width="match_parent"/>
  31. </LinearLayout>

res/layout/twopanes.xml:

  1. <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
  2. android:layout_width="fill_parent"
  3. android:layout_height="fill_parent"
  4. android:orientation="horizontal">
  5. <fragmentandroid:id="@+id/headlines"
  6. android:layout_height="fill_parent"
  7. android:name="com.example.android.newsreader.HeadlinesFragment"
  8. android:layout_width="400dp"
  9. android:layout_marginRight="10dp"/>
  10. <fragmentandroid:id="@+id/article"
  11. android:layout_height="fill_parent"
  12. android:name="com.example.android.newsreader.ArticleFragment"
  13. android:layout_width="fill_parent"/>
  14. </LinearLayout>

res/layout/twopanes_narrow.xml:

  1. <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
  2. android:layout_width="fill_parent"
  3. android:layout_height="fill_parent"
  4. android:orientation="horizontal">
  5. <fragmentandroid:id="@+id/headlines"
  6. android:layout_height="fill_parent"
  7. android:name="com.example.android.newsreader.HeadlinesFragment"
  8. android:layout_width="200dp"
  9. android:layout_marginRight="10dp"/>
  10. <fragmentandroid:id="@+id/article"
  11. android:layout_height="fill_parent"
  12. android:name="com.example.android.newsreader.ArticleFragment"
  13. android:layout_width="fill_parent"/>
  14. </LinearLayout>

现在所有可能的布局我们都已经定义了,唯一剩下的问题是使用方向限定词来匹配对应的布局给屏幕。这时候,你就可以使用布局别名的功能了:

res/values/layouts.xml:

  1. <resources>
  2. <itemname="main_layout"type="layout">@layout/onepane_with_bar</item>
  3. <boolname="has_two_panes">false</bool>
  4. </resources>
res/values-sw600dp-land/layouts.xml:
  1. <resources>
  2. <itemname="main_layout"type="layout">@layout/twopanes</item>
  3. <boolname="has_two_panes">true</bool>
  4. </resources>
res/values-sw600dp-port/layouts.xml:
  1. <resources>
  2. <itemname="main_layout"type="layout">@layout/onepane</item>
  3. <boolname="has_two_panes">false</bool>
  4. </resources>
res/values-large-land/layouts.xml:
  1. <resources>
  2. <itemname="main_layout"type="layout">@layout/twopanes</item>
  3. <boolname="has_two_panes">true</bool>
  4. </resources>
res/values-large-port/layouts.xml:
  1. <resources>
  2. <itemname="main_layout"type="layout">@layout/twopanes_narrow</item>
  3. <boolname="has_two_panes">true</bool>
  4. </resources>

7.使用.9.png图片

支持不同的屏幕尺寸同时也意味着你的图片资源也必须能兼容不同的屏幕尺寸。比如,一个button的背景图片就必须要适应该button的各种形状。

如果你在使用组件时可以改变图像的大小,你很快就会发现这是一个不明确的选择,因为运行的时候,图片会被拉伸或者压缩(这样容易造成图像失真)。避免这种情况的解决方案就是使用点9图片,这是一种能够指定哪些区域能够或者不能够拉伸的特殊png文件。

因此,在设计的图像需要与组件一起变大变小时,一定要使用点9.若要将位图转换为点9,你可以用一个普通的图像开始(下图,是在4倍变焦情况下的图像显示)。


你可以通过sdk中的draw9patch程序(位于tools/directory目录下)来画点9图片。通过沿左侧和顶部边框绘制像素来标记应该被拉伸的区域。也可以通过沿右侧和底部边界绘制像素来标记。就像下图所示一样:


请注意,上图沿边界的黑色像素。在顶部边框和左边框的那些表明图像的可拉伸区域,右边和底部边框则表示内容应该放置的地方。
此外,注意.9.png这个格式,你也必须用这个格式,因为框架会检测这是一个点9图片而不是一个普通图片。
当你将这个应用到组件的背景的时候(通过设置android:background="@drawable/button"),android框架会自动正确的拉伸图像以适应按钮的大小,下图就是各种尺寸中的显示效果:

原文链接:http://developer.android.com/training/multiscreen/screensizes.html

转自:http://hukai.me/android-training-course-in-chinese/ui/multiscreen/screen-sizes.html

分享到:
评论

相关推荐

    html5、移动端、mui+app尺寸适配、屏幕适配、屏幕自适应插件,解决不同手机尺寸的手机适配问题

    html5+app、移动端、mui+app尺寸适配、屏幕适配、屏幕自适应插件,解决不同手机尺寸的手机适配问题

    jQuery手机响应式设计焦点图,支持自动播放,根据屏幕大小动态放缩焦点图。兼容主流浏览器

    jQuery手机响应式设计焦点图,支持自动播放,根据屏幕大小动态放缩焦点图。兼容主流浏览器

    WM6下的房屋按揭贷款计算器

    本软件为绿色软件,目前版本为V1.0.0.0。只提供中文版本的,如果你的手机是英文版的WM,则会出现乱码;下一步把英文版本加进去。根据使用者反馈情况,适当加入其他...后续版本考虑兼容不同屏幕大小,视觉展示更协调。

    屏幕录像专家 免费录屏软件

    在VISTA/WIN7下运行本软件时,屏幕配色方案会自动暂时更改为Windows7 Basic,软件关闭时会自动恢复原来设置,这是为了减小录像的大小,不是软件兼容性问题,请不用担心。有些特殊情况确实不希望改变屏幕配色方案的,可以在...

    与浏览器兼容性好的屏幕取色器

    之前下过数次网页取色器...大小:68.0KB 使用方法:单击左侧的小取色器,(注:就是象photoshop里的工具取色器图标这个图标),按住不放,然后拖动鼠标移动到要获取颜色处松鼠标左键,即可得出取色参数在右侧顶白框里。

    屏幕录制专家

    在VISTA/WIN7下运行本软件时,屏幕配色方案会自动暂时更改为Windows7 Basic,软件关闭时会自动恢复原来设置,这是为了减小录像的大小,不是软件兼容性问题,请不用担心。有些特殊情况确实不希望改变屏幕配色方案的,可以在...

    iframe自适应高度,亲测完美兼容IE6-9,Chrome,Opera,firefox,safari

    因为有一个项目要用到iframe自适应高度,网上搜索了以下结果无数,不过看来看去都是那几个,而且基本都测试了一遍,所说的兼容根本不是那么回事,要不IE不正常,要不其他浏览器显示不正常,最后无奈,综合网上的方法...

    详解CSS3浏览器兼容

    不同浏览器其内核亦不尽相同,相同内核的版本不同,相同版本的内核浏览器品牌不一样,各种运行平台还存在差异、屏幕分辨率不一样,大小不一样,比例不一样。兼容性主要考虑三方面: 1)、CSS兼容 2)、JavaScript兼容 ...

    屏幕录像专家V2015 Build0903完美破解版.rar

    在VISTA/WIN7系统下运行本软件时,屏幕本色方案会自动暂时更改为WINDOWS7 BASIC,软件关闭时会自动恢复原来的设置,这是为了减小录像的大小,不是软件的兼容性问题,有些特殊情况确实不希望改变屏幕本色方案,可以...

    屏幕录像专家 v7.5 Build 20101215

    兼容性增强,细节完善 屏幕录像专家软件基本功能如下: 1.支持长时间录像并且保证声音同步。(V7以前的旧版本声音同步有问题,请使用最新版)。在硬盘空间足够的情况下,可以进行不限时间录象(V7.5版独有功能)。 2....

    电脑屏幕投屏工具 Deskreen 1.0.11.zip

    DESKREEN 功能 第二屏幕 使用任何带有 Web 浏览器的设备作为计算机的第二个屏幕 ...内存: 在一个屏幕共享会话中运行应用程序的平均大小为 250MB。每个新的屏幕共享会话平均需要高达 100MB 的额外内存才能流畅运行。

    可传递参数,根据参数自适应屏幕大小比例,可拖拽

    只需要在你在需要点击放大图的地方加入一个ID,然后写个简单的点击事件,调用这个包里的JS传递一个你想要放多大的参数即可使用。无BUG,兼容所有浏览器。移动端不清楚支持不支持。

    js判断页面的不同分辨率调用不同的css

    js判断页面的不同分辨率调用不同的css,对于网站在不同大小的屏幕下兼容性很有帮助。

    公司年会大屏幕抽奖

    更新:大屏幕右上角二维码增加中等大小的显示(3种大小状态,适合各种场景使用) 2017.8.6 更新:优化了一些js文件 更新:优化前台登录跳转页面的 更新:上墙消息增加了显示方式、循环播放设置、循环信息条数、放大显示...

    AndroidLauncherIconResizer:快速将图像大小从URL或文件调整为与Android兼容的Mipmap可绘制启动器图标,以适应各种屏幕密度

    快速将图像大小从URL或文件调整为与Android兼容的Mipmap可绘制启动器图标,以适应各种屏幕密度 用法 source venv/bin/activate pip install -r requirements.txt 然后,要使用该脚本,您可以从URL抓取图像: ...

    实时捕捉你桌面的屏幕录制软件 ALLCapture 3.0.zip

    ALLCapture 3.0 中文注册版是一款非常方便实用的软件,它可以让你实时捕捉桌面图片的软件,你可以全屏幕捕捉或者只是捕捉指定区域内的画面,并且捕捉的图片还可以创建为一个可以被导出为 Flash, MPEG(DVD,VCD,...

    Mobile焦点图带手滑效果

    完美兼容jQuery Mobile的一款带手滑效果的焦点图片切换,可根据屏幕大小自适应,以前在网站上找了很多,但效果都不理想,特意整理出,共享给大家。

    joomla responsive template

    兼容各种屏幕大小设备的joomla模板,支持1.5和2.5。

    SwissArmyKnife-android免root兼容所有版本ui调试工具.zip

    可以直接在android手机屏幕上显示当前Activity中所有控件(不管是否隐藏)的边界,内外边距大小,每一个控件大小,图片大小,字体颜色,大小,以及自定义信息。同时可以直接在屏幕上取色,另外还提供了直尺(单位为...

    屏幕录像工具--BB FlashBack Pro 4 专业版(附序列化和汉化补丁)

    完整控制音频和视频质量和文件大小。完整的回放控制在Flash和EXE文件导出中。 Vista 和Windows 7/8 兼容 捕获Vista和Windows7的“Aero”影响。BBFlashBack记录所有的图形模式。 XP 认证 微软已授权于BBFlashBack...

Global site tag (gtag.js) - Google Analytics