山海万灵 HarmonyOS 文化知识实战(02):响应式侧栏与多设备内容宽度
把“放大页面”改成“重算可用空间”文化知识应用的首页同时容纳探索路线、统计卡片、地图和底部导航。手机上最重要的是让单手浏览的内容不拥挤屏幕变宽后如果仍把全部区域按比例拉伸卡片之间会出现大块空白正文也会变成难以扫读的长行。真正需要响应的是页面结构而不是给每个组件单独写一组宽度。山海万灵把窗口宽高交给一个布局计算类。页面壳层只保存当前的screenWidthVp与screenHeightVp首页、图鉴、探索、馆长和“我的”都从同一个入口取得侧边距、内容宽度、卡片布局和底部安全留白。这样一来切换一级入口或进入详情时不会重新发明断点规则横向空间也不会被多个页面各自扣减。窗口条件页面壳层动作内容区结果宽度不足以放下侧栏保留底部导航内容从完整窗口宽度计算保持紧凑的阅读和点击节奏宽度与高度同时达到侧栏阈值为侧栏预留固定占位主内容不被导航覆盖内容区超过页面上限继续使用居中的最大内容宽度地图和说明文字不会无限拉长用宽度和高度共同决定导航形态只看宽度容易在矮窗口里误开侧栏导航虽然能排下内容和底部操作区却会互相挤压。因此侧栏判断同时约束宽度与高度。宽屏条件满足时壳层给侧栏留下 109vp 的占位不满足时这一占位为零内容可以完整使用窗口宽度。const SHANHAI_SIDE_NAV_MIN_WIDTH: number 840; const SHANHAI_SIDE_NAV_MIN_HEIGHT: number 520; const SHANHAI_SIDE_NAV_FOOTPRINT: number 109; static usesSideNavigation(windowWidthVp: number, windowHeightVp: number): boolean { return windowWidthVp SHANHAI_SIDE_NAV_MIN_WIDTH windowHeightVp SHANHAI_SIDE_NAV_MIN_HEIGHT; } static shellContentWidth(windowWidthVp: number, windowHeightVp: number): number { const sideNavigationWidth: number ShanhaiResponsive.usesSideNavigation(windowWidthVp, windowHeightVp) ? SHANHAI_SIDE_NAV_FOOTPRINT : 0; return Math.max(0, windowWidthVp - sideNavigationWidth); }这个判断把“导航在哪里”从各业务页面中移走。首页不需要知道设备类别图鉴也不需要自行扣除侧栏宽度它们只关心壳层已经算出的可用内容区。窗口高度不足时页面会自然回到不占侧栏宽度的形态避免一套只适合桌面比例的布局出现在窄高场景中。内容宽度、内边距与可读行长分开计算内容区宽度并不等于组件真实可用宽度。先扣除导航占位再以页面最大宽度限制阅读区域最后根据断点计算左右边距才能保证标题、地图说明和卡片正文都落在稳定的行长范围内。这里的“最大宽度”是阅读约束不是设备限制更大的窗口仍然可以展示更多背景与导航只是不让文字和交互卡片无限横向扩张。const SHANHAI_DEFAULT_PAGE_MAX_WIDTH: number 920; const SHANHAI_COMPACT_SIDE_INSET: number 14; const SHANHAI_MEDIUM_SIDE_INSET: number 20; const SHANHAI_WIDE_SIDE_INSET: number 24; static pageSideInset(windowWidthVp: number): number { if (windowWidthVp 840) return SHANHAI_WIDE_SIDE_INSET; if (windowWidthVp 600) return SHANHAI_MEDIUM_SIDE_INSET; return SHANHAI_COMPACT_SIDE_INSET; } static pageContentWidth(windowWidthVp: number, windowHeightVp: number): number { return Math.min( ShanhaiResponsive.shellContentWidth(windowWidthVp, windowHeightVp), SHANHAI_DEFAULT_PAGE_MAX_WIDTH ); } static pageInnerWidth(windowWidthVp: number, windowHeightVp: number): number { const pageWidth: number ShanhaiResponsive.pageContentWidth(windowWidthVp, windowHeightVp); return Math.max(0, pageWidth - ShanhaiResponsive.pageSideInset(windowWidthVp) * 2); }计算层次输入输出解决的问题壳层窗口宽高、侧栏判定shellContentWidth避免导航与正文重叠页面壳层宽度、页面最大宽度pageContentWidth控制长行文本与地图跨度组件页面宽度、左右内边距pageInnerWidth给卡片、网格和按钮稳定边界卡片列数从剩余宽度推导探索、馆长推荐和图鉴并不共用同一种卡片。通用功能卡以 420vp 为基准图鉴卡允许在更宽的内容区排成三列。两类组件都不直接读取屏幕宽度而是先使用已经扣除侧栏与内边距后的pageInnerWidth。这能避免一个页面刚打开侧栏另一个页面仍按旧宽度排两列的错位。static cardLayoutMode( windowWidthVp: number, windowHeightVp: number, baseCardWidth: number, gap: number 12 ): ShanhaiCardLayoutMode { const availableWidth: number ShanhaiResponsive.pageInnerWidth(windowWidthVp, windowHeightVp); if (availableWidth baseCardWidth) return COMPACT; if (availableWidth baseCardWidth * 2 gap) return PAIR; return SCALED_SINGLE; } static archiveColumns(windowWidthVp: number, windowHeightVp: number): number { const availableWidth: number ShanhaiResponsive.pageInnerWidth( windowWidthVp, windowHeightVp, 1360 ); if (availableWidth 420 * 3 12 * 2) return 3; if (availableWidth 420 * 2 12) return 2; return 1; }COMPACT、SCALED_SINGLE和PAIR把卡片的呈现选择限制在少量可解释状态空间不够时维持紧凑卡片中间区间使用单列缩放满足两张基准卡片与间距后再进入双列。图鉴使用同样的可用宽度原则但可根据档案页较大的内容上限返回一、二、三列。组件因此不必硬编码“手机”“平板”名称也能随分屏和浮窗的实际空间变化。页面壳层只分发结果不复制规则窗口变化发生在最外层容器。区域变化回调更新宽高状态后首页把已计算好的isWideScreen、内容宽度、边距和底部留白传给内容组件图鉴、探索和馆长页面则接收各自需要的网格或卡片模式。布局计算类保持纯函数使组件在状态刷新时只消费结果不在渲染过程中修改设备状态。.onAreaChange((_oldValue: Area, newValue: Area) { const width: number Math.round(Number(newValue.width)); const height: number Math.round(Number(newValue.height)); if (width 0 width ! this.screenWidthVp) { this.screenWidthVp width; } if (height 0 height ! this.screenHeightVp) { this.screenHeightVp height; } }) ShanhaiHomePageContent({ isWideScreen: this.isWideScreen(), contentWidth: this.pageContentWidth(), horizontalInset: this.pageSideInset(), bottomInset: this.pageBottomInset(), panelItemWidth: this.adaptivePanelItemWidth() })手机运行界面中探索路线、三项统计、地图和底部五个入口处于同一内容节奏底部导航没有压住“继续探索”操作区。进入更大的可用窗口时导航形态、边距、内容上限和卡片列数都沿着这条计算链重新得出而不是由业务页面追加一套特例。验收时关注空间契约而非单个像素响应式页面的回归重点是“同一份状态在不同可用空间中仍能阅读和操作”。可依次检查在窄窗口确认底部导航和操作区不覆盖在满足侧栏阈值的窗口确认主内容已扣除导航占位在图鉴页观察一、二、三列切换时项目宽度与间距是否稳定在窗口变化后返回首页确认探索进度和当前入口没有被布局刷新重置。还有一个容易被忽略的边界窗口宽度变化不应触发业务数据重载。布局函数只读取宽高并返回数字或枚举探索进度、已发现神兽和当前区域仍由页面状态与数据层维护。这样在旋转、分屏或浮窗调整时组件可以重新排版却不会把用户带回初始路线也不会因为一次尺寸变化重新请求内容。把尺寸计算与业务状态分离后布局问题更容易定位卡片过窄先检查可用宽度和间距数据不刷新再检查状态链路两类问题不会互相掩盖。HarmonyOS 的响应式布局能力可以参考 官方响应式布局指南。把空间计算收口到页面壳层之后后续增加地图详情、馆长推荐或知识图谱卡片时只需选择适合的布局函数而不需要在每个新页面重写设备分支。

相关新闻

使用Cheat Engine修改《植物大战僵尸》游戏数据的完整指南

使用Cheat Engine修改《植物大战僵尸》游戏数据的完整指南

1. 为什么选择Cheat Engine修改《植物大战僵尸》作为一款经典的塔防游戏,《植物大战僵尸》凭借其独特的玩法和幽默的风格风靡全球。但对于部分玩家来说,反复挑战同一关卡可能会感到枯燥,这时候使用Cheat Engine(简称CE&#xff09…

2026/10/18 18:56:00 阅读更多 →
彻底解决ROS开发中rosdep keys未解析错误:从诊断到根治的完整指南

彻底解决ROS开发中rosdep keys未解析错误:从诊断到根治的完整指南

1. 问题引入:当ROS开发遇上“rosdep keys”未解析的拦路虎 如果你正在Ubuntu上搭建ROS(Robot Operating System)开发环境,或者尝试编译一个包含众多第三方依赖的ROS工作空间,那么你大概率见过下面这个令人头疼的错误信…

2026/10/17 17:55:17 阅读更多 →
Python中deque与Queue的对比与选型指南

Python中deque与Queue的对比与选型指南

1. 为什么需要区分deque和Queue?在Python中处理数据序列时,我们经常面临一个选择:该用collections.deque还是queue.Queue?这个问题看似简单,但选错数据结构可能导致性能问题甚至线程安全问题。我曾在实际项目中遇到过因…

2026/10/17 18:16:11 阅读更多 →

最新新闻

GitHub 开源趋势日报 | 2026年10月8日:AI Agent 与 TypeScript 项目实战配置指南

GitHub 开源趋势日报 | 2026年10月8日:AI Agent 与 TypeScript 项目实战配置指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 19:43:30 阅读更多 →
插入排序为何在工程中比冒泡更受欢迎?

插入排序为何在工程中比冒泡更受欢迎?

1. 项目概述:从一道经典面试题切入真实工程选择逻辑“为什么插入排序比冒泡排序更受欢迎?”——这道题常出现在算法入门课的期末卷、校招笔试的选择题第3题,甚至某次技术面中面试官随口一问。但如果你真以为这只是在考“谁交换次数少”或者“…

2026/10/18 19:43:30 阅读更多 →
Claude Code 权限模式完全指南:Auto、Bypass、Ask 三模式深度解析与 TaoToken 接入实践

Claude Code 权限模式完全指南:Auto、Bypass、Ask 三模式深度解析与 TaoToken 接入实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 19:43:30 阅读更多 →
Unity3D快抢红包互动小游戏开发全流程:从玩法设计到真机适配踩坑记录

Unity3D快抢红包互动小游戏开发全流程:从玩法设计到真机适配踩坑记录

做活动互动开发的人应该都有感觉,需求方现在越来越不满足于“摇一摇”“扫码抽奖”这种老套路,点名要的往往是更有画面感、更刺激的玩法。Unity3D 快抢红包互动小游戏这类项目,就是在这种需求里反复出现的类型:大屏上倒计时跳动&a…

2026/10/18 19:43:30 阅读更多 →
本地化AI代码评审系统:Java静态分析与GLM-4双通道实践

本地化AI代码评审系统:Java静态分析与GLM-4双通道实践

简介:这是一套面向Java中高级开发者与AI工程实践者的代码质量提升工具,聚焦于利用人工智能技术实现Java代码的自动化评审与漏洞识别,适用于CI/CD集成、团队代码规范统一及个人代码健壮性自查等场景。资源共34个文件,含24个Java核心…

2026/10/18 19:43:30 阅读更多 →
Cursor Agent 文件写入频繁要求确认 — 排查记录与 TaoToken 配置实践

Cursor Agent 文件写入频繁要求确认 — 排查记录与 TaoToken 配置实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 19:42:30 阅读更多 →

日新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 0:55:02 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/17 17:22:31 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 12:16:16 阅读更多 →