包含 View 的响应式/自适应设计

响应式/自适应布局提供经过优化的用户体验, 屏幕尺寸实现响应式/自适应布局, 基于视图的应用,以支持所有显示屏尺寸、屏幕方向和 配置,包括可调整大小的配置,例如多窗口模式 模式

自适应设计

要支持各种外形规格的设备,第一步是创建一个 可适应可用显示空间大小的变化的布局 应用

ConstraintLayout

要创建自适应布局,最好的方法是使用 ConstraintLayout 作为界面的基本布局借助 ConstraintLayout,您可以指定 根据各个视图之间的空间关系确定每个视图的位置和大小, 视图。然后,所有视图都可以随着 显示空间的变化

如需使用 ConstraintLayout 构建布局,最简单的方法是使用 Android Studio 中的布局编辑器。利用布局编辑器,您可以将新视图拖动到 对父视图和同级视图应用约束条件,并设置视图 而无需手动修改任何 XML。

图 3. Android Studio 中的布局编辑器,显示了一个 ConstraintLayout

如需了解详情,请参阅使用 ConstraintLayout

自适应宽度和高度

为了确保您的布局能够适应不同的显示尺寸,请使用 wrap_contentmatch_parent0dp (match constraint) 视图组件的高度,而不是硬编码值:

  • wrap_content:视图设置自己的尺寸以适应其包含的内容。
  • match_parent:视图在父视图中尽可能地展开。
  • 0dp (match constraint):在 ConstraintLayout 中,类似于 match_parent。视图会占用视图界面内的所有可用空间 限制条件。

例如:

<TextView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="@string/lorem_ipsum" />

图 4 显示了 TextView 的宽度和高度在显示时如何调整 宽度会随着设备屏幕方向而发生变化。

图 4. 一个自适应 TextView

TextView 会设置其宽度,以填充所有可用空间 (match_parent), 高度与所包含空间的高度所需的空间相同 文本 (wrap_content),使视图能够适应不同的显示屏 和不同量的文字。

如果您使用的是LinearLayout,则 也可以根据布局展开子视图 权重,让视图按比例填充 可用空间。但是,在嵌套的 LinearLayout 中使用权重需要 系统执行多次布局传递,以确定每个布局的大小 视图,这会降低界面性能。

ConstraintLayout 可以使用 而 LinearLayout 不会影响性能,因此请将嵌套 LinearLayoutConstraintLayout。之后您 可以定义具有约束条件的加权布局 链

自适应设计

应用的布局应始终可适应不同的显示屏尺寸。 不过,即使是自适应布局也无法 支持多窗口模式或多窗口模式例如,您之前看到的界面 可能无法在手机屏幕上提供最佳用户体验 平板电脑。自适应设计提供针对不同需求进行了优化的备用布局 尺寸。

对列表-详情界面使用 SlidingPaneLayout

“列表-详情”界面通常会针对以下情况提供不同的用户体验: 不同尺寸的屏幕在大屏设备上,列表窗格和详情窗格 通常是并排显示选择列表中的某个项目后,项目信息 显示在详情窗格中而不更改界面,两个窗格仍保留 图片。不过,在小屏幕上,这两个窗格是分开显示的, 就会占据整个显示区域列表窗格中的项 则详情窗格(包含所选项的信息)会替换 列表窗格。返回导航会将详情窗格替换为列表窗格。

SlidingPaneLayout 管理用于确定两种用户体验中的哪一种 与当前窗口大小相称:

<?xml version="1.0" encoding="utf-8"?>
<androidx.slidingpanelayout.widget.SlidingPaneLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recycler_view"
        android:layout_width="280dp"
        android:layout_height="match_parent"
        android:layout_gravity="start" />

    <androidx.fragment.app.FragmentContainerView
        android:id="@+id/nav_host_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="300dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        app:defaultNavHost="true"
        app:navGraph="@navigation/item_navigation" />

</androidx.slidingpanelayout.widget.SlidingPaneLayout>

以下文件中包含的两个视图的 layout_widthlayout_weight 属性: SlidingPaneLayout 决定了 SlidingPaneLayout 行为。在本示例中, 如果窗口足够大(至少 580dp 宽),可以同时显示这两个视图, 这些窗格会并排显示但是,如果窗口宽度小于 580dp,窗格可以相互滑动以单独占据整个应用 窗口。

如果窗口宽度大于指定的最小总宽度 (580dp), layout_weight 值可用于按比例调整两个窗格的大小。在 例如,列表窗格始终为 280dp 宽,因为它没有权重。 不过,详情窗格将始终填充超过 580dp 的任何水平空间,因为 视图的 layout_weight 设置。

备用布局资源

如需让界面设计适应变化多种多样的显示屏尺寸,请使用备用布局 由资源识别 限定符

图 5. 同一应用针对不同的屏幕尺寸使用不同的布局。

您可以通过创建额外的屏幕,提供特定于屏幕的自适应布局 应用源代码中的 res/layout/ 目录。为每个集群创建一个目录 需要不同布局的屏幕配置。然后附加一个屏幕 将配置限定符设置为 layout 目录名称(例如 layout-w600dp(适用于可用宽度为 600dp 的屏幕)。

这些配置限定符表示 应用界面系统会考虑所有系统装饰元素(如 导航栏)和窗口配置更改(例如多窗口模式, 模式)。

如需在 Android Studio 中创建备用布局,请参阅使用布局变体 针对不同屏幕进行优化 使用 View 开发界面

“最小宽度”限定符

最小宽度屏幕尺寸限定符可让您提供 适用于具有最小宽度(以密度无关)测量的显示屏的布局 像素 (dp)。

Android 通过以 dp 为度量单位来描述屏幕尺寸,支持你创建 专为特定显示屏尺寸而设计的,无需考虑 不同的像素密度。

例如,您可以创建一个名为 main_activity 并针对 在手机和平板电脑中创建文件的不同版本 目录:

res/layout/main_activity.xml           # For phones (smaller than 600dp smallest width)
res/layout-sw600dp/main_activity.xml   # For 7" tablets (600dp wide or wider)

“最小宽度”限定符用于指定显示屏两侧的最小尺寸, 而不管设备当前的屏幕方向如何,通过这种方式可以指定 您的布局可用的总体显示大小。

下面是其他最小宽度值与典型屏幕尺寸的对应关系:

  • 320dp:小手机屏幕(240x320 ldpi、320x480 mdpi、480x800 hdpi 等)
  • 480dp:约为 5 英寸的大手机屏幕 (480x800 mdpi)
  • 600dp:7 英寸平板电脑 (600x1024 mdpi)
  • 720dp:10 英寸平板电脑(720x1280 mdpi、800x1280 mdpi 等)

下图更详细地说明了不同屏幕 dp 宽度对应于不同的屏幕尺寸和方向。

图 6. 建议的宽度划分点,以支持不同的屏幕尺寸。

最小宽度限定符的值为 dp,因为重要的是 系统考虑像素密度后可用的显示空间量 (不是原始像素分辨率)。

您使用资源限定符(如最小宽度)指定的尺寸为 而不是实际屏幕尺寸而是指定宽度或高度 应用窗口可用的 dp 单位。Android 系统可能会使用 系统界面的屏幕部分(如 屏幕或顶部的状态栏),因此部分屏幕可能无法 适合您的布局。如果您的应用在多窗口模式下使用, 应用只能获取应用所在窗口的尺寸。当 调整窗口大小时,会触发配置 会随着新窗口大小的变化 使系统能够选择合适的布局文件。因此,资源 您声明的限定符尺寸应仅指定应用所需的空间。 在为以下设备提供空间时,系统会考虑系统界面使用的所有空间 自定义布局

“可用宽度”限定符

您无需根据显示屏的最小宽度更改布局, 可能需要根据可用宽度或高度来更改布局。 例如,您可能想在屏幕每次显示时都使用双窗格布局 提供至少 600dp 的宽度,该宽度可能会根据 设备处于横屏或竖屏模式。在这种情况下,您应该使用 可用宽度限定符,如下所示:

res/layout/main_activity.xml         # For phones (smaller than 600dp available width)
res/layout-w600dp/main_activity.xml  # For 7" tablets or any screen with 600dp available width
                                     # (possibly landscape phones)

如果您的应用担心可用高度,您可以使用 可用高度限定符。例如,layout-h600dp 表示屏幕的 屏幕高度至少为 600dp。

“屏幕方向”限定符

尽管您也许可以只使用 也希望当用户在纵向模式切换时改变用户体验 和横向模式。

为此,您可以将 portland 限定符添加到布局目录中 名称。只需确保屏幕方向限定符在尺寸限定符之后即可。 例如:

res/layout/main_activity.xml                # For phones
res/layout-land/main_activity.xml           # For phones in landscape
res/layout-sw600dp/main_activity.xml        # For 7" tablets
res/layout-sw600dp-land/main_activity.xml   # For 7" tablets in landscape

有关所有屏幕配置限定符的更多信息,请参阅应用 资源概览

窗口大小类别

窗口大小类别是视口断点,有助于您创建自适应尺寸 布局。这些断点将可供应用使用的显示区域标识为 compactmediumexpanded。宽度和高度是单独指定的 因此,对于宽度,您的应用始终具有窗口大小类别, 高度。

如需以编程方式应用自适应布局,请执行以下操作:

如需了解详情,请参阅窗口大小 类

使用 fragment 将界面组件模块化

在针对多种显示屏尺寸设计应用时,请使用 fragment 来提取 将界面逻辑拆分为单独的组件,以确保 跨 activity 重复界面行为。然后,您可以将 fragment 组合起来, 在大屏设备上创建多窗格布局,也可以将 fragment 放置在 单独的 activity。

例如,列表-详情模式(请参阅 SlidingPaneLayout)的应用,只需 fragment(包含列表)和另一个包含列表项的 fragment 。在大屏幕上,fragment 可以并排显示;已开启 逐个填充屏幕

如需了解详情,请参阅 fragment 概览。

activity 嵌入

如果您的应用由多个 activity 组成,activity 嵌入让您能够: 轻松创建自适应界面

activity 嵌入会显示多个 activity 或 。在大屏设备上 activity 可以并排显示;在小屏幕上 堆叠一个在顶部 相互独立。

您可以通过创建 XML 文件来确定应用如何显示其 activity 供系统用来确定 根据显示大小调整呈现方式或者,您可以将Jetpack WindowManager API 调用。

activity 嵌入支持设备屏幕方向更改和可折叠设备, 在设备旋转或折叠和展开时堆叠和取消堆叠 activity。

有关详情,请参阅 Activity 嵌入

屏幕尺寸和宽高比

针对各种屏幕尺寸和宽高比测试应用,以确保您的界面 正确扩缩。

Android 10(API 级别 29)及更高版本支持各种宽高比。 可折叠设备的外形规格可能有所不同,长而窄的屏幕,例如屏幕为 21:9 折叠时,展开时宽高比为 1:1 的方形宽高比。

为了确保与尽可能多的设备兼容,请测试您的应用, 以下屏幕宽高比之一:

图 7. 各种屏幕宽高比。

如果您无法提供满足您的所有不同屏幕尺寸的设备 您可以使用 Android 模拟器模拟 几乎可以适应任何屏幕尺寸

如果您希望在真实设备上进行测试,但没有设备,则可以使用 Firebase Test Lab 以访问 Google 数据中心内的多台设备。

其他资源