实现动态加载布局

前言

怎么能让程序根据设备分辨率或屏幕大小的不同来动态加载布局呢?

虽然动态添加 Fragment 的功能很强大,但也只是在一个布局文件中添加或替换 Fragment。要实现以上需求,就要用到 Android 的 资源限定符(Resource Qualifiers) 机制了,它能让我们在不同设备上提供不同的布局。

使用最小宽度限定符

在过去,你可能会使用 largexlarge 等限定符来区分设备,但因其定义太过模糊,所以早已不被官方推荐使用了。目前推荐使用最小宽度限定符(sw<N>dp)来区分设备。

其中 sw 是 Smallest-width 的缩写,表示设备屏幕最短边的宽度值,单位为 dp。它可以让我们给屏幕的宽度指定一个最小值,屏幕宽度大于等于这个值的设备就加载一套布局,小于这个值的设备就加载另一套布局。

注意:这个值并不会随着屏幕旋转而改变,这是一个固定值。

实战

来到之前的 FragmentTest 项目中,我们的目标是:在手机上就会显示新闻标题列表,在平板上,左侧区域显示新闻标题列表,右侧区域显示新闻详情。

项目在这篇博客中:Fragment 入门教程:从核心概念到实践操作

在默认的 res/layout/activity_main.xml 布局文件中:

xml 复制代码
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal">

    <androidx.fragment.app.FragmentContainerView
        android:id="@+id/leftFrag"
        android:name="com.example.fragmenttest.LeftFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>

只保留左侧的 Fragment 容器,并且让它充满父布局的可用空间,这个布局用于手机。

然后,在 res 目录下新建 layout-sw600dp 文件夹,当设备的最小宽度大于等于 600dp 时,会加载这个文件夹下的布局。在该文件夹下新建一个布局文件,也叫 activity_main.xml,代码如下:

xml 复制代码
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal">

    <androidx.fragment.app.FragmentContainerView
        android:id="@+id/leftFrag"
        android:name="com.example.fragmenttest.LeftFragment"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1" />

    <androidx.fragment.app.FragmentContainerView
        android:id="@+id/rightFrag"
        android:name="com.example.fragmenttest.RightFragment"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="3" />
</LinearLayout>

这个布局用于平板。在程序运行时,在平板上,系统会自动加载 layout-sw600dp/activity_main 布局,而在手机上,会自动加载 layout/activity_main 布局。

运行效果

在平板上的运行效果:

在手机上的运行效果:

这样,我们就借助了最小宽度限定符实现了程序在运行时动态加载布局的功能。

常见限定符

常见的限定符如下表所示:

屏幕特征 限定符 描述
最小宽度 sw<N>dp 屏幕最短边的 dp 值,不随方向改变。
可用宽度 w<N>dp 当前可用的宽度的 dp 值,会随方向改变。
可用高度 h<N>dp 当前可用的高度的 dp 值,会随方向改变。
方向 land, port 横屏或竖屏。
屏幕密度 ldpi, mdpi, hdpi, xhdpi, xxhdpi 每英寸像素点的数量。

其中最小宽度可用于区分手机/平板设备的动态布局。方向可提供特定方向下的布局。而屏幕密度主要用于 Drawable 图片资源的适配,确保图片清晰度,很少用于动态布局。

相关推荐
张小潇20 分钟前
AOSP15 Input专题InputDispatcher源码分析
android
TT_Close23 分钟前
【Flutter×鸿蒙】debug 包也要签名,这点和 Android 差远了
android·flutter·harmonyos
Kapaseker2 小时前
2026年,我们还该不该学编程?
android·kotlin
雨白18 小时前
Android 快捷方式实战指南:静态、动态与固定快捷方式详解
android
hqk18 小时前
鸿蒙项目实战:手把手带你实现 WanAndroid 布局与交互
android·前端·harmonyos
LING18 小时前
RN容器启动优化实践
android·react native
恋猫de小郭21 小时前
Flutter 发布官方 Skills ,Flutter 在 AI 领域再添一助力
android·前端·flutter
Kapaseker1 天前
一杯美式搞懂 Any、Unit、Nothing
android·kotlin
黄林晴1 天前
你的 Android App 还没接 AI?Gemini API 接入全攻略
android
恋猫de小郭2 天前
2026 Flutter VS React Native ,同时在 AI 时代 VS Native 开发,你没见过的版本
android·前端·flutter