Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .agents/skills/mpx2rn/references/rn-script-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -587,11 +587,13 @@ setAppHide()
| `getCurrentPages()` | 返回当前导航栈中已映射的页面实例列表(顺序与路由 state 相关)。 |
| `setAppShow()` | 手动触发应用「进入前台」逻辑,驱动已注册的 `onShow`。 |
| `setAppHide()` | 手动触发应用「进入后台」逻辑,驱动已注册的 `onHide`。 |
| `notifyDimensionsChange(dimensions?)` | 主动通知框架 dimensions 发生变化,触发 rpx、vw、vh、媒体查询、onResize 等的重新计算。不传参时默认使用当前屏幕 dimensions 并重新执行 `customDimensions`。 |

#### 注意事项

- 勿在 App 构造函数执行完成前依赖 `getApp()` 内业务字段已赋值完毕;与路由相关的初始化宜放在 `onLaunch` / `onShow`。
- `getCurrentPages()` 依赖 React Navigation 焦点与 `__mpxPagesMap`,与原生小程序栈细节不完全相同。
- `notifyDimensionsChange` 由框架在首次样式计算时自动注入,需在开始渲染后才可调用。

---

Expand Down
1 change: 0 additions & 1 deletion docs-vitepress/guide/rn/application-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -463,7 +463,6 @@ createComponent({

例如: 在折叠屏中我们期望只在其中一半屏上展示,可在 customDimensions 中判断当前是否为折叠屏展开状态,如果是则将 ScreenWidth 设置为原来的一半。


### 前后台切换 {#app-state-change}

#### mpx.config.rnConfig.disableAppStateListener
Expand Down
2 changes: 2 additions & 0 deletions packages/core/@types/global.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,5 @@ declare module '*?resolve' {

declare let setAppShow: () => void
declare let setAppHide: () => void

declare let notifyDimensionsChange: (dimensions?: { window: import('react-native').ScaledSize; screen: import('react-native').ScaledSize }) => void
6 changes: 3 additions & 3 deletions packages/core/@types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -376,9 +376,9 @@ export interface RnConfig {
* @param dimensions 包含 window 和 screen 的尺寸信息
* @returns 返回修改后的尺寸对象,或 void 表示不修改
*/
customDimensions?: <T extends { window: ScaledSize; screen: ScaledSize }>(
dimensions: T
) => T | void
customDimensions?: (
dimensions: { window: ScaledSize; screen: ScaledSize }
) => { window: ScaledSize; screen: ScaledSize } | void

/**
* 加载并执行异步分包的方法。
Expand Down
53 changes: 36 additions & 17 deletions packages/core/src/platform/builtInMixins/styleHelperMixin.ios.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,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({})
Expand All @@ -18,30 +18,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()
Expand All @@ -52,7 +62,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尺寸错误,并触发多次问题
Expand All @@ -79,8 +93,13 @@ const unit = {

const empty = {}

let dimensionsApplied = false
function formatValue (value, unitType) {
if (!dimensionsInfoInitialized) useDimensionsInfo(global.__mpxAppDimensionsInfo)
// 懒初始化:首次调用时将初始 dimensions 写入全局(触发 customDimensions 处理)
if (!dimensionsApplied) {
dimensionsApplied = true
applyDimensionsInfo(global.__mpxAppDimensionsInfo)
}
if (unitType === 'hairlineWidth') {
return StyleSheet.hairlineWidth
}
Expand Down
Loading