Socket
Book a DemoInstallSign in
Socket

react-native-keyboard-insets

Package Overview
Dependencies
Maintainers
1
Versions
10
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

react-native-keyboard-insets

A powerful Keyboard Aware View for React Native

1.3.5
latest
Source
npmnpm
Version published
Maintainers
1
Created
Source

react-native-keyboard-insets

A powerful Keyboard Aware View for React Native.

使用简单,自动模式下不需要额外代码来处理键盘。

自动模式手动模式
README-2023-02-02-15-56-36README-2023-02-18-21-36-20

本库主要依据 Android 官方指南 Synchronize animation with the software keyboard 来实现,同时参考了 react-native-keyboard-controller。因为该库不是很符合我的需求,所以我自己写了一个。

Installation

yarn add react-native-keyboard-insets

iOS

cd ios
pod install

Android

开启 edge-to-edge。 这将使得 APP 的 UI 撑满整个屏幕,而不是被系统 UI(譬如虚拟导航键)遮挡,从而实现更摩登的 UI 效果。

// MainActivity.java
import androidx.core.view.WindowCompat;

public class MainActivity extends ReactActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(null);
        // enable Edge-to-Edge
        WindowCompat.setDecorFitsSystemWindows(getWindow(), false);
    }
}

为了更好的向后(Android 10 以前)兼容, 在 AndroidManifest 中设置 android:windowSoftInputMode="adjustResize"

<!-- AndroidManifest.xml -->
<activity
  android:name=".MainActivity"
    ...
  android:windowSoftInputMode="adjustResize">
  <intent-filter>
    ...
  </intent-filter>
</activity>

开启 Edge-to-Edge 后,你的 UI 会撑满整个屏幕,可使用 react-native-safe-area-context 来处理和系统 UI (譬如虚拟导航键) 重叠的部分。

可参考以下代码进行全局处理,也可以每个页面单独处理,以实现更美观更摩登的 UI 效果。

import { Platform } from 'react-native'
import { SafeAreaProvider, SafeAreaView } from 'react-native-safe-area-context'

function App() {
  return (
    <SafeAreaProvider>
      <NavigationContainer>...</NavigationContainer>
      {Platform.OS === 'android' && <SafeAreaView mode="margin" edges={['bottom']} />}
    </SafeAreaProvider>
  )
}

如果使用 hybrid-navigation 作为导航组件,则不需要做任何事情,因为它已经帮你处理好了。

Usage

使用 KeyboardInsetsView 代替 View 作为容器,或者使用 KeyboardInsetsViewScrollView 包裹起来。当键盘显示或隐藏时,KeyboardInsetsView 会自动调整自身的位置,以保证输入框不被键盘遮挡。

import { KeyboardInsetsView } from 'react-native-keyboard-insets'

function MyComponent() {
  return (
    <KeyboardInsetsView extraHeight={16} style={{ flex: 1 }}>
      <ScrollView>
        ...
        <TextInput />
        ...
      </ScrollView>
    </KeyboardInsetsView>
  )
}

Support Nested.

import { KeyboardInsetsView } from 'react-native-keyboard-insets'

function MyComponent() {
  return (
    <KeyboardInsetsView extraHeight={16} style={{ flex: 1 }}>
      ...
      <KeyboardInsetsView extraHeight={8}>
        <TextInput />
      </KeyboardInsetsView>
      ...
    </KeyboardInsetsView>
  )
}

KeyboardInsetsView 本质上是个 View,所以你可以使用 View 的所有属性,也可以和 View 互相替换。

KeyboardInsetsView 有两个额外的属性:

  • extraHeight:自动模式下,键盘总是紧贴着输入框的下边缘,这个属性设置输入框距离键盘的额外高度。KeyboardInsetsView 的最大偏移受键盘高度限制,若加入额外高度后,KeyboardInsetsView 偏移距离大于键盘高度,将产生截断,此时 KeyboardInsetsView 偏移距离等于键盘高度,底部将与键盘顶部相贴

  • onKeyboard:是个回调函数,一旦设置,就进入手动模式,KeyboardInsetsView 不会帮你调整输入框的位置。你需要利用这个回调函数实现自己想要的效果。

    onKeyboard 的参数声明如下:

    interface KeyboardState {
      height: number // 键盘的高度,不会因为键盘隐藏而变为 0
      shown: boolean // 当键盘将隐已隐时,这个值为 false;当键盘将显已显时,这个值为 true
      transitioning: boolean // 键盘是否正在显示或隐藏
      position: Animated.Value // 键盘的位置,从 0 到 height,可以用来实现动画效果
    }
    

API

  • useKeyboard

    为了方便用户编写 onKeyboard 回调,keyboard-insets 提供了一个 useKeyboard hook,使用方法如下:

    import { useKeyboard } from 'react-native-keyboard-insets'
    
    function MyComponent() {
      const { keyboard, onKeyboard } = useKeyboard()
    
      console.log(keyboard.height), // 键盘的高度
    
      return (
        <KeyboardInsetsView onKeyboard={onKeyboard}>
          <TextInput />
        </KeyboardInsetsView>
      )
    }
    
  • getEdgeInsetsForView

    有时候你需要知道某个 View 距离屏幕四边的距离,这个时候就可以使用 getEdgeInsetsForView 方法。

    import { getEdgeInsetsForView } from 'react-native-keyboard-insets'
    
    function MyComponent() {
      const inputRef = useRef<TextInput>(null)
    
      const onLayout = useCallback(() => {
        const viewTag = findNodeHandle(inputRef.current)
        if (viewTag === null) {
          return
        }
    
        // 获得 TextInput 距离屏幕四边的距离
        getEdgeInsetsForView(viewTag, insets => {
          console.log('insets', insets)
        })
      }, [])
    
      return (
        <View>
          <TextInput ref={inputRef} onLayout={onLayout} />
        </View>
      )
    }
    

运行 example 项目

首先 clone 本项目

git clone git@github.com:listenzz/react-native-keyboard-insets.git
cd react-native-keyboard-insets

然后在项目根目录下运行如下命令:

yarn install
# &
yarn start

在 Android 上运行

首先,确保你有一个模拟器或设备

如果熟悉原生开发,使用 Android Studio 打开 example/android,像运行原生应用那样运行它,也可以使用命令行:

# 在项目根目录下运行
yarn android

你可能需要运行如下命令,才可以使用 Hot Reload 功能

adb reverse tcp:8081 tcp:8081

在 iOS 上运行

首先安装 cocoapods 依赖,在项目根目录下运行如下命令:

cd example/ios && pod install
# 成功安装依赖后,回到根目录
cd -

如果熟悉原生开发,使用 Xcode 打开 example/ios,像运行原生应用那样运行它,或者使用命令行:

# 在项目根目录下运行
yarn ios

Keywords

react-native

FAQs

Package last updated on 14 Mar 2023

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

About

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.

  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc

U.S. Patent No. 12,346,443 & 12,314,394. Other pending.