-
Notifications
You must be signed in to change notification settings - Fork 392
feat: RN 新增 notifyDimensionsChange 配置,支持手动触发 dimensions 更新 #2485
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
8bc0c29
2cbd765
d02e51b
904d176
dc37d71
cc92b32
080c1b2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,8 +5,8 @@ import { reactive } from '../../observer/reactive' | |
| import Mpx from '../../index' | ||
|
|
||
| global.__mpxAppDimensionsInfo = { | ||
| window: Dimensions.get('window'), | ||
| screen: Dimensions.get('screen') | ||
| window: Object.assign({}, Dimensions.get('window')), | ||
| screen: Object.assign({}, Dimensions.get('screen')) | ||
| } | ||
| global.__mpxSizeCount = 0 | ||
| global.__mpxPageSizeCountMap = reactive({}) | ||
|
|
@@ -19,30 +19,40 @@ global.__GCC = function (className, classMap, classMapValueCache) { | |
| return classMapValueCache.get(className) | ||
| } | ||
|
|
||
| let dimensionsInfoInitialized = false | ||
| function useDimensionsInfo (dimensions) { | ||
| dimensionsInfoInitialized = true | ||
| function getPageSize (screen = global.__mpxAppDimensionsInfo.screen) { | ||
| return screen.width + 'x' + screen.height | ||
| } | ||
|
|
||
| // 将 dimensions 写入全局(支持 customDimensions 自定义),返回最终生效的 dimensions | ||
| function applyDimensionsInfo (dimensions) { | ||
| if (typeof Mpx.config.rnConfig?.customDimensions === 'function') { | ||
| dimensions = Mpx.config.rnConfig.customDimensions(dimensions) || dimensions | ||
| } | ||
| global.__mpxAppDimensionsInfo.window = dimensions.window | ||
| global.__mpxAppDimensionsInfo.screen = dimensions.screen | ||
| return dimensions | ||
| } | ||
|
|
||
| function getPageSize (window = global.__mpxAppDimensionsInfo.screen) { | ||
| return window.width + 'x' + window.height | ||
| } | ||
|
|
||
| Dimensions.addEventListener('change', ({ window, screen }) => { | ||
| const oldScreen = getPageSize(global.__mpxAppDimensionsInfo.screen) | ||
| useDimensionsInfo({ window, screen }) | ||
| function onDimensionsChange (dimensions) { | ||
| const oldScreen = getPageSize() | ||
| /** | ||
| * 鸿蒙上在屏幕尺寸不变时,调用 Dimensions.get 获取到的返回值都是同一个对象, | ||
| * 为防止外部修改dimensions导致影响其他位置调用Dimensions.get的返回,所以clone一份进行后续处理 | ||
| */ | ||
| if (!dimensions) { | ||
| dimensions = { | ||
| window: Dimensions.get('window'), | ||
| screen: Dimensions.get('screen') | ||
| } | ||
| } | ||
| applyDimensionsInfo({ window: Object.assign({}, dimensions.window), screen: Object.assign({}, dimensions.screen) }) | ||
|
|
||
| // 对比 screen 高宽是否存在变化 | ||
| if (getPageSize(screen) === oldScreen) return | ||
| // screen 高宽未变化时不触发 resize 副作用 | ||
| if (getPageSize() === oldScreen) return | ||
|
|
||
| global.__classCaches?.forEach(cache => cache?.clear()) | ||
|
|
||
| // 更新全局和栈顶页面的标记,其他后台页面的标记在show之后更新 | ||
| // 更新全局和栈顶页面的标记,其他后台页面的标记在 show 之后更新 | ||
| global.__mpxSizeCount++ | ||
|
|
||
| const navigation = getFocusedNavigation() | ||
|
|
@@ -53,7 +63,11 @@ Dimensions.addEventListener('change', ({ window, screen }) => { | |
| global.__mpxPageStatusMap[navigation.pageId] = `resize${global.__mpxSizeCount}` | ||
| } | ||
| } | ||
| }) | ||
| } | ||
| // 默认实现:不传参时通过 Dimensions 实时获取当前屏幕尺寸(拷贝一份防止原对象被外部修改) | ||
| global.notifyDimensionsChange = onDimensionsChange | ||
|
|
||
| Dimensions.addEventListener('change', onDimensionsChange) | ||
|
|
||
| // TODO: 1 目前测试鸿蒙下折叠屏screen固定为展开状态下屏幕尺寸,仅window会变化,且window包含状态栏高度 | ||
| // TODO: 2 存在部分安卓折叠屏机型在折叠/展开切换时,Dimensions监听到的width/height尺寸错误,并触发多次问题 | ||
|
|
@@ -82,8 +96,13 @@ const empty = {} | |
|
|
||
| const isNum = (v) => !isNaN(+v) | ||
|
|
||
| let dimensionsApplied = false | ||
| function formatValue (value, unitType) { | ||
| if (!dimensionsInfoInitialized) useDimensionsInfo(global.__mpxAppDimensionsInfo) | ||
| // 懒初始化:首次调用时将初始 dimensions 写入全局(触发 customDimensions 处理) | ||
| if (!dimensionsApplied) { | ||
| dimensionsApplied = true | ||
| applyDimensionsInfo(global.__mpxAppDimensionsInfo) | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [P2] 首次样式计算前发生尺寸通知,会重复应用 customDimensions dimensionsApplied 只在 formatValue() 中置为 true。如果此前收到原生 Dimensions change 事件或调用 notifyDimensionsChange(),onDimensionsChange() 已经应用了 customDimensions,但这里仍会对转换后的全局尺寸再次执行转换。 已用 PR 与基线对照复现:配置 customDimensions 为 dimensions => { dimensions.screen.width /= 2 },原始宽度 800,通知后宽度为 400,首次计算 750rpx 时却得到 200;基线在相同原生事件顺序下正确得到 400。这会导致布局与媒体查询使用错误尺寸,也影响已有的原生尺寸事件路径。 建议在 applyDimensionsInfo() 中统一维护初始化标记,恢复原实现“任何入口应用尺寸后均视为已初始化”的语义,并补充尺寸事件发生在首次样式计算前的回归测试。 |
||
| } | ||
| if (unitType && typeof unit[unitType] === 'function') { | ||
| return unit[unitType](+value) | ||
| } | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[P3] 修正 API 注入时机,并补齐用户文档
这里写的是“首次样式计算时自动注入”,但实现是在 styleHelperMixin.ios.js 模块加载时直接执行 global.notifyDimensionsChange = onDimensionsChange,与首次 formatValue() 调用无关,建议按实际实现修正说明。
此外,docs-vitepress/guide/rn/application-api.md 在本 PR 中仅删除空行,没有新增 notifyDimensionsChange 的使用说明,尚未满足仓库对新增公开 API 的文档同步要求。建议在折叠屏适配章节补充参数、无参时从 Dimensions.get 读取原始尺寸并重新执行 customDimensions 的行为,以及调用示例。