Skip to content

Commit 3b4cade

Browse files
authored
Merge pull request #2218 from didi/feat/keyboardAvoding
feat: android 键盘拉起行为与 ios 统一
2 parents bc55372 + 60b1dfe commit 3b4cade

10 files changed

Lines changed: 283 additions & 220 deletions

File tree

packages/core/@types/index.d.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,13 @@ export interface RnConfig {
381381
* @param packages 分包名数组
382382
*/
383383
downloadChunkAsync?: (packages: Array<string>) => void
384+
385+
/**
386+
* bundle 中是否关闭 android 键盘避让功能,如果关闭需要将该配置设置为 false,使用 mpx 内置的键盘避让逻辑
387+
* @platform android
388+
* @default true
389+
*/
390+
enableNativeKeyboardAvoiding?: boolean
384391
}
385392

386393
interface MpxConfig {

packages/core/src/platform/createApp.ios.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { createElement, memo, useRef, useEffect } from 'react'
1010
import * as ReactNative from 'react-native'
1111
import { initAppProvides } from './export/inject'
1212
import { NavigationContainer, createNativeStackNavigator, SafeAreaProvider, GestureHandlerRootView } from './env/navigationHelper'
13-
import { innerNav } from './env/nav'
13+
import MpxNav from '@mpxjs/webpack-plugin/lib/runtime/components/react/dist/mpx-nav'
1414

1515
const appHooksMap = makeMap(mergeLifecycle(LIFECYCLE).app)
1616

@@ -66,8 +66,8 @@ export default function createApp (options) {
6666
flex: 1
6767
}
6868
},
69-
createElement(innerNav, {
70-
pageConfig: pageConfig,
69+
createElement(MpxNav, {
70+
pageConfig,
7171
navigation
7272
}),
7373
children

packages/core/src/platform/env/nav.js

Lines changed: 0 additions & 137 deletions
This file was deleted.

packages/core/src/platform/patch/getDefaultOptions.ios.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import {
1717
RouteContext
1818
} from '@mpxjs/webpack-plugin/lib/runtime/components/react/dist/context'
1919
import { PortalHost, useSafeAreaInsets } from '../env/navigationHelper'
20-
import { useInnerHeaderHeight } from '../env/nav'
20+
import { useInnerHeaderHeight } from '@mpxjs/webpack-plugin/lib/runtime/components/react/dist/mpx-nav'
2121

2222
function getSystemInfo () {
2323
const windowDimensions = ReactNative.Dimensions.get('window')

packages/webpack-plugin/lib/runtime/components/react/context.ts

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,13 @@ export type LabelContextValue = MutableRefObject<{
66
triggerChange: (evt: NativeSyntheticEvent<TouchEvent>) => void
77
}>
88

9-
export type KeyboardAvoidContextValue = MutableRefObject<
10-
{ cursorSpacing: number, ref: MutableRefObject<any> } | null
11-
>
9+
export type KeyboardAvoidContextValue = MutableRefObject<{
10+
cursorSpacing: number
11+
ref: MutableRefObject<any>
12+
adjustPosition: boolean
13+
keyboardHeight?: number
14+
onKeyboardShow?: () => void
15+
} | null>
1216

1317
export interface GroupValue {
1418
[key: string]: { checked: boolean; setValue: Dispatch<SetStateAction<boolean>> }
@@ -37,13 +41,13 @@ export interface IntersectionObserver {
3741
}
3842

3943
export interface PortalContextValue {
40-
mount: (children: React.ReactNode, key?: number | null, id?: number| null) => number| undefined
44+
mount: (children: React.ReactNode, key?: number | null, id?: number | null) => number | undefined
4145
update: (key: number, children: React.ReactNode) => void
4246
unmount: (key: number) => void
4347
}
4448

4549
export interface ScrollViewContextValue {
46-
gestureRef: React.RefObject<any> | null,
50+
gestureRef: React.RefObject<any> | null
4751
scrollOffset: Animated.Value
4852
}
4953

@@ -53,7 +57,7 @@ export interface RouteContextValue {
5357
}
5458

5559
export interface StickyContextValue {
56-
registerStickyHeader: Function,
60+
registerStickyHeader: Function
5761
unregisterStickyHeader: Function
5862
}
5963

packages/webpack-plugin/lib/runtime/components/react/mpx-input.tsx

Lines changed: 38 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -280,8 +280,8 @@ const Input = forwardRef<HandlerRef<TextInput, FinalInputProps>, FinalInputProps
280280
}
281281

282282
const setKeyboardAvoidContext = () => {
283-
if (adjustPosition && keyboardAvoid) {
284-
keyboardAvoid.current = { cursorSpacing, ref: nodeRef }
283+
if (keyboardAvoid) {
284+
keyboardAvoid.current = { cursorSpacing, ref: nodeRef, adjustPosition }
285285
}
286286
}
287287

@@ -296,19 +296,42 @@ const Input = forwardRef<HandlerRef<TextInput, FinalInputProps>, FinalInputProps
296296

297297
const onFocus = (evt: NativeSyntheticEvent<TextInputFocusEventData>) => {
298298
setKeyboardAvoidContext()
299-
bindfocus && bindfocus(
300-
getCustomEvent(
301-
'focus',
302-
evt,
303-
{
304-
detail: {
305-
value: tmpValue.current || ''
306-
},
307-
layoutRef
308-
},
309-
props
310-
)
311-
)
299+
300+
if (bindfocus) {
301+
const focusAction = () => {
302+
bindfocus(
303+
getCustomEvent(
304+
'focus',
305+
evt,
306+
{
307+
detail: {
308+
value: tmpValue.current || '',
309+
height: keyboardAvoid?.current?.keyboardHeight
310+
},
311+
layoutRef
312+
},
313+
props
314+
)
315+
)
316+
if (keyboardAvoid?.current?.onKeyboardShow) {
317+
keyboardAvoid.current.onKeyboardShow = undefined
318+
}
319+
}
320+
if (keyboardAvoid?.current) {
321+
// 有 keyboardAvoiding
322+
if (keyboardAvoid.current.keyboardHeight) {
323+
// iOS: keyboard 获取高度时机 keyboardWillShow 在 input focus 之前,可以立即执行
324+
focusAction()
325+
} else {
326+
// Android,Harmony: keyboard 获取高度时机 keyboardDidShow 在 input focus 之后,需要延迟回调
327+
evt.persist()
328+
keyboardAvoid.current.onKeyboardShow = focusAction
329+
}
330+
} else {
331+
// 无 keyboardAvoiding,直接执行 focus 回调
332+
focusAction()
333+
}
334+
}
312335
}
313336

314337
const onBlur = (evt: NativeSyntheticEvent<TextInputFocusEventData>) => {

0 commit comments

Comments
 (0)