六、支持不同的屏幕尺寸

安卓 3.0 只适用于大屏幕设备。然而,安卓冰淇淋三明治适用于所有小屏幕和大屏幕设备。开发人员应该创建支持大、小屏幕尺寸的应用。本章将展示设计支持不同屏幕尺寸的用户界面的方法。

本章涵盖的主题如下:

  • 使用match_parentwrap_content
  • 使用九补丁
  • 使用dip代替px

安卓 4.0 支持不同的屏幕尺寸

安卓设备和 种类繁多,因此有许多不同的屏幕尺寸。

下图(来源opensignalmaps.com)显示了安卓设备片段:

Android 4.0 supports different screen sizes

如图所示,设备种类繁多(近 4000 种不同的设备)。这意味着许多不同的屏幕尺寸和密度。安卓可以缩放和调整你的安卓应用的用户界面。然而,这始终是不够的。例如,为小屏幕设计的用户界面将被安卓放大为大屏幕。这在大屏幕上看起来不太好。大屏幕上的空间应该得到有效利用,大屏幕的用户界面应该不同于小屏幕的用户界面。Android 提供了一些 API 来设计适合不同屏幕尺寸和密度的用户界面。您应该使用这些应用编程接口来使您的应用在不同的屏幕尺寸和密度下看起来很好。这样可以增加安卓应用的用户体验。

为 安卓应用设计用户界面需要考虑的事项如下:

  • 屏幕尺寸:这是设备的物理屏幕尺寸。智能手机和平板电脑的屏幕尺寸可能在 2.5 英寸到 10.1 英寸之间。
  • 分辨率:这是设备在每个维度上的像素数。通常定义为宽度×高度,如 640×480。
  • 屏幕密度:这是一个物理区域的最大像素数。在一个区域内,高密度屏幕的像素比低密度屏幕多。
  • 屏幕方向:设备可能处于 风景或人像模式。当处于横向模式时,其宽度增加。

使用 match_parent 和 wrap_content

match_parentwrap_content可以用来设置视图的 layout_heightlayout_width属性。当使用match_parent时,安卓会扩展视图,使其大小与其父视图相同。当使用wrap_content时,安卓根据其内容的大小扩展视图。也可以使用像素值设置宽度和高度。但是,使用像素值并不是一个好的做法,因为像素的数量会根据屏幕属性而变化,并且给定的像素值在每个屏幕中的大小并不相同。在下面的示例中,我们使用像素值来设置视图的宽度和高度。布局 XML 代码显示在以下代码块中:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <TextView
 android:layout_width="240px"
 android:layout_height="30px"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:padding="@dimen/padding_medium"
        android:text="hello world1 hello world 2 hello world 3 hello"
        tools:context=".Chapter6_1Activity" />

</RelativeLayout>

前面布局 XML 文件中使用的@dimen等一些定义将在本书的源代码文件中提供。

从代码中可以看到,我们将layout_width设置为240px,将layout_height设置为30px。我们将在三个具有不同屏幕属性的不同模拟器中执行这个应用。模拟器属性如下:

  • Small Screen Properties: This configuration is for small screens. These properties can be configured as shown in the following screenshot:

    Using match_parent and wrap_content

  • Normal Screen Properties: This configuration is for normal screens. These properties can be configured as shown in the following screenshot:

    Using match_parent and wrap_content

  • Large Screen Properties: This configuration is for large screens. These properties can be configured as shown in the following screenshot:

    Using match_parent and wrap_content

当该应用在之前的仿真器配置中执行时,屏幕将如下所示:

Using match_parent and wrap_content

正如你在截图中看到的,它在小屏幕上看起来很好。然而,在正常屏幕上,文本被裁剪,并且 TextView组件的所有内容并不可见。在大屏幕上,什么也看不见。此示例表明,使用像素作为宽度和高度值并不是一种好的做法。

现在,我们将使用 wrap_contentmatch_parent来设置高度和宽度长度。布局 XML 代码如下所示:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <TextView
 android:layout_width="match_parent"
 android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:padding="@dimen/padding_medium"
        android:text="hello world1 hello world 2 hello world 3 hello"
        tools:context=".Chapter6_1Activity" />

</RelativeLayout>

当应用以相同的仿真器配置执行时,屏幕将如下所示:

Using match_parent and wrap_content

在这张截图中可以看到,应用在每个仿真器和屏幕配置中看起来都是一样的,并且显示了 TextView组件的所有内容。因此,使用 wrap_contentmatch_parent是设计用户界面的最佳实践。

用 dip 代替 px

上一个样本的另一个选项是使用dip(密度无关像素)值,而不是px值。这样,TextView 组件在不同的屏幕尺寸下会看起来几乎一样。代码如下所示:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <TextView
 android:layout_width="350dip"
 android:layout_height="40dip"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:padding="@dimen/padding_medium"
        android:text="hello world1 hello world 2 hello world 3 hello"
        tools:context=".Chapter6_1Activity" />

</RelativeLayout>

在这段代码中可以看到,我们使用dip值作为宽度和高度。如果您在上一节定义的模拟器中执行这个应用,它看起来如下:

Using dip instead of px

类型

对于字体大小,可以使用 sp(比例无关像素)单位代替 px。

省略使用绝对布局

绝对布局是一个不推荐使用的布局,它为视图使用固定的位置。AbsoluteLayout不是设计用户界面的好方法因为在不同的屏幕尺寸下看起来不一样。我们将通过以下示例布局看到这一点:

<?xml version="1.0" encoding="utf-8"?>
<AbsoluteLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/textView5"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
 android:layout_x="96dp"
 android:layout_y="8dp"
        android:text="Text Top"
        android:textAppearance="?android:attr/textAppearanceLarge" />

    <TextView
        android:id="@+id/textView4"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
 android:layout_x="89dp"
 android:layout_y="376dp"
        android:text="Text Bottom"
        android:textAppearance="?android:attr/textAppearanceLarge" />

</AbsoluteLayout>

正如您在这个 XML 代码中看到的,固定位置用于AbsoluteLayout中的视图。当这个应用在 前面部分定义的仿真器中执行时,它看起来如下:

Omit using AbsoluteLayout

正如您在屏幕截图中看到的,底部的文本在小屏幕上不可见,但在其他屏幕上可见。在用户界面设计上,AbsoluteLayout 并不是一个好的 做法。

为不同的屏幕密度提供不同的位图绘图

安卓根据屏幕密度缩放位图。但是,如果只提供一个位图,图像就不会好看。图像会看起来模糊或损坏。为不同的屏幕密度提供不同的位图绘图是一个很好的实践。在下面的截图中,使用了两个图像按钮。为第一个图像按钮提供不同的位图可绘制,为第二个图像按钮提供低密度位图可绘制。从截图中可以看到,第二个图像按钮中的位图看起来比较模糊;但是,第一个图像按钮中的位图看起来很好。

Providing different bitmap drawables for different screen densities

类型

如果图像被放在drawable-nodpi文件夹 中,它们将不会被缩放。

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

安卓缩放布局,使其适合设备屏幕。然而,这在某些情况下是不够的。在第 5 章片段中,我们开发了一个应用,列出了书籍,当点击一本书时,就会显示该书的作者。

以下是小屏幕上显示的屏幕截图:

Providing different layouts for different screen sizes

对于更大的屏幕,这种设计不是一个好的选择。用户界面看起来会很糟糕。我们应该有效地利用大屏幕中的空间。我们可以对较大的屏幕使用不同的布局,将较小屏幕上显示的两个屏幕结合起来。用户界面应该如下所示:

Providing different layouts for different screen sizes

布局文件应该放在适当的文件夹中。比如大屏幕的布局文件要放在res/layout-large文件夹,小屏幕的布局文件要放在res/layout-small文件夹。

除了现有的屏幕尺寸限定符之外,安卓 3.2 在中引入了新的屏幕尺寸限定符。新限定词如下:

  • sw<N>dp:这个限定词定义了 的最小宽度。比如res/layout-sw600dp/
    • 当屏幕宽度至少为N dp 时,无论屏幕方向如何,都使用该文件夹中的布局文件。
  • w<N>dp:这个限定词定义了确切的可用 宽度。比如res/layout-w600dp/
  • h<N>dp:这个限定词定义了确切的可用高度。例如res/layout-h600dp/

九贴

九补丁功能允许使用可拉伸位图作为资源。位图根据定义的可拉伸区域进行拉伸。可拉伸区域由 1 像素宽度的黑线定义。以下是一个可绘制的九补丁示例:

Nine-patch

图像文件应放入扩展名为的可绘制文件夹中。 9.png 顶部和左侧黑线定义了可拉伸区域,底部和右侧黑线定义了适合内容的可拉伸区域。

有一个工具叫做绘制 9-patch ,和安卓 SDK 捆绑在一起。你可以很容易地用这个编辑器创建九补丁图像。

总结

在本章中,我们学习了一些设计指南,以支持不同的屏幕尺寸和密度。我们不应该使用硬编码像素值来定义布局宽度和高度。相反,我们应该使用wrap_contentmatch_parent属性,或者使用dip值而不是px值。我们应该为不同的屏幕尺寸使用不同的布局,以使应用在所有屏幕尺寸下看起来都很好。我们还学习了使用九补丁规则来创建可拉伸位图。开发完应用后,我们应该在安卓模拟器中测试不同屏幕大小和密度的应用,看看它的外观。通过这种方式,我们可以检测用户界面的问题和缺陷。

在下一章中,我们将了解安卓兼容包,并了解如何使用它。