响应式/自适应布局提供经过优化的用户体验, 屏幕尺寸实现响应式/自适应布局, 基于视图的应用,以支持所有显示屏尺寸、屏幕方向和 配置,包括可调整大小的配置,例如多窗口模式 模式。
自适应设计
要支持各种外形规格的设备,第一步是创建一个 可适应可用显示空间大小的变化的布局 应用
ConstraintLayout
要创建自适应布局,最好的方法是使用
ConstraintLayout
作为界面的基本布局借助 ConstraintLayout
,您可以指定
根据各个视图之间的空间关系确定每个视图的位置和大小,
视图。然后,所有视图都可以随着
显示空间的变化
如需使用 ConstraintLayout
构建布局,最简单的方法是使用 Android Studio 中的布局编辑器。利用布局编辑器,您可以将新视图拖动到
对父视图和同级视图应用约束条件,并设置视图
而无需手动修改任何 XML。
如需了解详情,请参阅使用 ConstraintLayout。
自适应宽度和高度
为了确保您的布局能够适应不同的显示尺寸,请使用
wrap_content
、match_parent
或 0dp (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
的宽度和高度在显示时如何调整
宽度会随着设备屏幕方向而发生变化。
TextView
会设置其宽度,以填充所有可用空间 (match_parent
),
高度与所包含空间的高度所需的空间相同
文本 (wrap_content
),使视图能够适应不同的显示屏
和不同量的文字。
如果您使用的是LinearLayout
,则
也可以根据布局展开子视图
权重,让视图按比例填充
可用空间。但是,在嵌套的 LinearLayout
中使用权重需要
系统执行多次布局传递,以确定每个布局的大小
视图,这会降低界面性能。
ConstraintLayout
可以使用
而 LinearLayout
不会影响性能,因此请将嵌套
LinearLayout
至
ConstraintLayout
。之后您
可以定义具有约束条件的加权布局
链。
自适应设计
应用的布局应始终可适应不同的显示屏尺寸。 不过,即使是自适应布局也无法 支持多窗口模式或多窗口模式例如,您之前看到的界面 可能无法在手机屏幕上提供最佳用户体验 平板电脑。自适应设计提供针对不同需求进行了优化的备用布局 尺寸。
对列表-详情界面使用 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_width
和 layout_weight
属性:
SlidingPaneLayout
决定了 SlidingPaneLayout
行为。在本示例中,
如果窗口足够大(至少 580dp 宽),可以同时显示这两个视图,
这些窗格会并排显示但是,如果窗口宽度小于
580dp,窗格可以相互滑动以单独占据整个应用
窗口。
如果窗口宽度大于指定的最小总宽度 (580dp),
layout_weight
值可用于按比例调整两个窗格的大小。在
例如,列表窗格始终为 280dp 宽,因为它没有权重。
不过,详情窗格将始终填充超过 580dp 的任何水平空间,因为
视图的 layout_weight
设置。
备用布局资源
如需让界面设计适应变化多种多样的显示屏尺寸,请使用备用布局 由资源识别 限定符。
您可以通过创建额外的屏幕,提供特定于屏幕的自适应布局
应用源代码中的 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 宽度对应于不同的屏幕尺寸和方向。
最小宽度限定符的值为 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。
“屏幕方向”限定符
尽管您也许可以只使用 也希望当用户在纵向模式切换时改变用户体验 和横向模式。
为此,您可以将 port
或 land
限定符添加到布局目录中
名称。只需确保屏幕方向限定符在尺寸限定符之后即可。
例如:
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
有关所有屏幕配置限定符的更多信息,请参阅应用 资源概览。
窗口大小类别
窗口大小类别是视口断点,有助于您创建自适应尺寸 布局。这些断点将可供应用使用的显示区域标识为 compact、medium 或 expanded。宽度和高度是单独指定的 因此,对于宽度,您的应用始终具有窗口大小类别, 高度。
如需以编程方式应用自适应布局,请执行以下操作:
- 根据窗口大小类别断点创建布局资源
- 使用
WindowSizeClass#compute()
函数(位于 Jetpack WindowManager 中) 库 - 膨胀当前窗口大小类的布局资源
如需了解详情,请参阅窗口大小 类。
使用 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 的方形宽高比。
为了确保与尽可能多的设备兼容,请测试您的应用, 以下屏幕宽高比之一:
如果您无法提供满足您的所有不同屏幕尺寸的设备 您可以使用 Android 模拟器模拟 几乎可以适应任何屏幕尺寸
如果您希望在真实设备上进行测试,但没有设备,则可以使用 Firebase Test Lab 以访问 Google 数据中心内的多台设备。
其他资源
- Material Design - 了解布局