【官网最新翻译】安卓支持不同的屏幕尺寸

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


本课程将告诉您如何支持不同的屏幕尺寸通过一下方式:

  • 确保你的布局可以充分调整大小以适应屏幕
  • 根据屏幕配置提供适当的UI布局
  • 确保正确的布局应用到正确的屏幕
  • 提供了正确缩放位图

使用“ wrap_content ”和“ match_parent ”

为了确保你的布局非常灵活并且适应不同的屏幕尺寸,你应该使用“ wrap_content ”和“ match_parent ”为某些视图组件设置宽度和高度。如果您使用“ wrap_content ” ,视图的宽度或高度设置为所需的最小尺寸,以适应该视图中的内容,而“ 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 ”,而不是具体的尺寸。这使得布局正确适应不同的屏幕尺寸和方向。
例如,这就是这种布局在纵向和横向的模式。请注意,该部件的尺寸的宽度和高度自动适应:

图1:在纵向(左)和横向(右)的新闻阅读器示例应用程序。

使用相对布局

您可以使用LinearLayout和嵌套实例“ wrap_content ”和“ match_parent ”大小的组合构造相当复杂的布局。但是,LinearLayout中不允许您精确地控制子视图之间的空间关系。在LinearLayout中视图只是简单的一个接一个的排列。如果您需要子视图被排列不是一条直线,更好的解决方案往往是用一个RelativeLayout ,它允许你指定组件之间的空间关系的布局。例如,您可以对齐左侧的一个子视图,并对齐在屏幕右侧的另一个视图。

例如:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        android:id="@+id/label"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Type here:"/>
    <EditText
        android:id="@+id/entry"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/label"/>
    <Button
        android:id="@+id/ok"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/entry"
        android:layout_alignParentRight="true"
        android:layout_marginLeft="10dp"
        android:text="OK" />
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toLeftOf="@id/ok"
        android:layout_alignTop="@id/ok"
        android:text="Cancel" />
</RelativeLayout>
图2 显示了这种布局出现在QVGA屏幕上。

图2:QVGA屏幕(小屏幕)

图3 显示了它如何出现在大屏幕上

图3:WSVGA屏幕(大屏幕)


请注意,尽管元件的尺寸发生改变,它们的空间关系被作为指定的RelativeLayout.LayoutParams保留。

使用限定的大小

就像在前面的章节中描述,就只有这么多好处可以从灵活的布局或相对布局得到的。当这些屏幕拉伸内部或者周围的组件以适应不同的屏幕,他们可能不会为每个屏幕提供最佳的用户体验。因此,您的应用程序不应该只实现灵活的布局,也应该提供几种可供选择的布局,以针对不同的屏幕配置。允许根据当前设备的配置(如不同的布局设计不同的屏幕尺寸)运行时会自动选择合适的资源。


例如,许多应用程序 为大屏幕实现“两个窗格”的图案(应用程序可能会显示 项目清单在一个窗格中,并在另一个窗格中显示内容) 。平板电脑和电视是足够大 屏幕同时显示两个窗格,但在手机屏幕必须单独显示它们。因此,要实现这些布局,你可以有以下文件:

  • res/layout/main.xml, 单窗格 (默认) 布局:
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <fragment android:id="@+id/headlines"
                  android:layout_height="fill_parent"
                  android:name="com.example.android.newsreader.HeadlinesFragment"
                  android:layout_width="match_parent" />
    </LinearLayout>
  • res/layout-large/main.xml, 双窗格布局:
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="horizontal">
        <fragment android:id="@+id/headlines"
                  android:layout_height="fill_parent"
                  android:name="com.example.android.newsreader.HeadlinesFragment"
                  android:layout_width="400dp"
                  android:layout_marginRight="10dp"/>
        <fragment android:id="@+id/article"
                  android:layout_height="fill_parent"
                  android:name="com.example.android.newsreader.ArticleFragment"
                  android:layout_width="fill_parent" />
    </LinearLayout>
请注意,备选的大的版面的目录名。大屏幕的设备(例如,7英寸的平板甚至更大)才会选择这个布局,小设备将选择默认的。

使用最小宽度限定

在3.2之前的安装设备上开发者遇到的一个难题是大屏幕尺寸,这包括戴尔Streak ,原来的Galaxy Tab ,和一般的7英寸平板电脑。但是,许多应用程序可能需要显示不同的布局在这个类别(如10英寸和7英寸的设备)在不同的设备,即使他们都被认为是“大”屏幕。这就是为什么Android的推出了“最小宽度”限定于Android3.2版本

最小的宽度限定可以让您针对那些在dp上给定最小宽度的屏幕。例如,典型的7英寸平板电脑拥有600dp的最小宽度,如果你希望你的用户界面拥有两个窗格(但在小屏幕上只有一个单独窗格),你可以使用跟上一节一样的两种布局,但对大尺寸进行限定,使用sw600dp来表示使用两个窗格布局的最小屏幕的最小宽度是600dp:

  • res/layout/main.xml, single-pane (default) layout:
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <fragment android:id="@+id/headlines"
                  android:layout_height="fill_parent"
                  android:name="com.example.android.newsreader.HeadlinesFragment"
                  android:layout_width="match_parent" />
    </LinearLayout>
  • res/layout-sw600dp/main.xml, two-pane layout:
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="horizontal">
        <fragment android:id="@+id/headlines"
                  android:layout_height="fill_parent"
                  android:name="com.example.android.newsreader.HeadlinesFragment"
                  android:layout_width="400dp"
                  android:layout_marginRight="10dp"/>
        <fragment android:id="@+id/article"
                  android:layout_height="fill_parent"
                  android:name="com.example.android.newsreader.ArticleFragment"
                  android:layout_width="fill_parent" />
    </LinearLayout>
这意味着设备,其最小宽度大于或等于600dp将选择layout-sw600dp/main.xml (两窗格)布局,而小屏幕会选择布局/ main.xml中(单面板)的布局。

但是,你会发现,这并不会让3.2之前的设备工作很好,因为他们不承认sw600dp作为大小备选,所以你仍然需要使用大的预选,所以,你应该有一个名为res/layout-large/main.xml和res/layout-sw600dp/main.xml等同,在下一节中,你会看到一种技术,可以让你避免重复布局文件这种方式。


使用布局别名

最小宽度预选仅使用在Android 3.2及以上。因此,你应该也还是使用抽象尺寸(small, normal, large and xlarge )与早期版本兼容。例如,如果你想设计自己的界面,让它显示在手机上的单窗格的用户界面,但7英寸平板电脑,电视等大型设备多窗格用户界面,你就必须提供这些文件:
  • res/layout/main.xml: single-pane layout
  • res/layout-large: multi-pane layout
  • res/layout-sw600dp: multi-pane layout
最后两个文件是相同的,因为其中一人将和搭载Android 3.2的设备进行匹配,而另一个和早期版本做匹配。
为了避免这种重复相同的文件(维护的头痛起因于它) ,你可以使用别名文件。例如,您可以定义如下布局:
  • res/layout/main.xml, single-pane layout
  • res/layout/main_twopanes.xml, two-pane layout
并且添加以下两个文件:
  • res/values-large/layout.xml:
    <resources>
        <item name="main" type="layout">@layout/main_twopanes</item>
    </resources>
  • res/values-sw600dp/layout.xml:
    <resources>
        <item name="main" type="layout">@layout/main_twopanes</item>
    </resources>
这后两个文件具有相同的内容,但它们实际上并不定义布局。他们只是设立一个别名到main_twopanes 。它们应用到平板电脑和电视,无论什么Android版本(3.2版本之前的平板电脑和电视机相匹配 values-large/,3.2版本之后将匹配 values-sw600dp ) 。

使用方向限定
一些布局在横向和纵向方向运行良好,但大多可以从调整中受益。在新闻阅读器示例应用程序,下面是如何布局的行为在每个屏幕大小和方向:


  • small screen, portrait: single pane, with logo
  • small screen, landscape: single pane, with logo
  • 7" tablet, portrait: single pane, with action bar
  • 7" tablet, landscape: dual pane, wide, with action bar
  • 10" tablet, portrait: dual pane, narrow, with action bar
  • 10" tablet, landscape: dual pane, wide, with action bar
  • TV, landscape: dual pane, wide, with action bar

所以,这些布局在res/layout/ directory中的XML文件中定义。然后向每个布局分配到各个屏幕的配置中,应用程序使用别名布局将它们匹配到每个配置

res/layout/onepane.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <fragment android:id="@+id/headlines"
              android:layout_height="fill_parent"
              android:name="com.example.android.newsreader.HeadlinesFragment"
              android:layout_width="match_parent" />
</LinearLayout>

res/layout/onepane_with_bar.xml:

<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>

res/layout/twopanes.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="horizontal">
    <fragment android:id="@+id/headlines"
              android:layout_height="fill_parent"
              android:name="com.example.android.newsreader.HeadlinesFragment"
              android:layout_width="400dp"
              android:layout_marginRight="10dp"/>
    <fragment android:id="@+id/article"
              android:layout_height="fill_parent"
              android:name="com.example.android.newsreader.ArticleFragment"
              android:layout_width="fill_parent" />
</LinearLayout>

res/layout/twopanes_narrow.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="horizontal">
    <fragment android:id="@+id/headlines"
              android:layout_height="fill_parent"
              android:name="com.example.android.newsreader.HeadlinesFragment"
              android:layout_width="200dp"
              android:layout_marginRight="10dp"/>
    <fragment android:id="@+id/article"
              android:layout_height="fill_parent"
              android:name="com.example.android.newsreader.ArticleFragment"
              android:layout_width="fill_parent" />
</LinearLayout>
所有可能的布局文件都已经定义,现在你可以用别名技术分别对应相关的配置

res/values/layouts.xml:

<resources>
    <item name="main_layout" type="layout">@layout/onepane_with_bar</item>
    <bool name="has_two_panes">false</bool>
</resources>

res/values-sw600dp-land/layouts.xml:

<resources>
    <item name="main_layout" type="layout">@layout/twopanes</item>
    <bool name="has_two_panes">true</bool>
</resources>

res/values-sw600dp-port/layouts.xml:

<resources>
    <item name="main_layout" type="layout">@layout/onepane</item>
    <bool name="has_two_panes">false</bool>
</resources>

res/values-large-land/layouts.xml:

<resources>
    <item name="main_layout" type="layout">@layout/twopanes</item>
    <bool name="has_two_panes">true</bool>
</resources>

res/values-large-port/layouts.xml:

<resources>
    <item name="main_layout" type="layout">@layout/twopanes_narrow</item>
    <bool name="has_two_panes">true</bool>
</resources>

使用Nine-patch图

什么是nine-patch图,参考http://www.cnblogs.com/feisky/archive/2010/01/16/1649502.html 或者往下看

支持不同的屏幕尺寸通常意味着你的图片资源也必须能适应不同大小的。例如,一个按钮的背景必须适合任何将它应用到的按钮形状。

如果您使用可以改变大小的简单图像在组件上,你会很快发现,结果是比印象中的稍差,因为运行时会伸长或收缩均匀的图像。解决方案是使用nine-patch图,这是特殊格式PNG文件指示哪些区域能够和不能够被拉伸。

因此,当用到的图片需要随着组件一起变化的时候,使用nine-patch图。你可以使用普通的图片转化成nine-patch图片(图4 ,在4倍变焦的清晰显示)。

图4. button.png

然后通过SDK的draw9patch实用程序(它位于tools/ directory下)运行它,您可以在其中通过沿左侧和顶部边框绘制像素标记应该被拉伸的区域。你也可以标记应该通过绘制像素沿右侧和底部边界,如图5。

图5. button.9.png

请注意,沿边界黑色像素。在顶部边框和左边框的那些黑点表明在这些地方图像可拉伸,在右边和底部边框表示其中应该放置内容。

此外,请注意图片的扩展名:.9.png,你必须使用这个扩展,因为这是框架检测nine-patch图片的方式,而不是一个普通的图片。

当你为组件提供这样的背景(可以设置android:background="@drawable/button")),该框架正确地拉伸图像以容纳按钮的大小,如图6中各种尺寸。

图6. A button using the button.9.png nine-patch in various sizes.



Figure 6. A button using the button.9.png nine-patch in various sizes.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值