ReactNative: 使用键盘避免视图KeyboardAvoidingView组件实现键盘自适应

Posted xyq-208910

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ReactNative: 使用键盘避免视图KeyboardAvoidingView组件实现键盘自适应相关的知识,希望对你有一定的参考价值。

一、简介

在前面使用了TextInput实现了文本输入和搜索功能,一般情况下,我们会通过样式设置把控键盘弹起后与视图的间距,以至于不会挡住某些视图。但是,如果视图上的组件比较多,键盘的弹起覆盖某些视图几乎是无法避免的。ReactNative中就提供了一个KeyboardAvoidingView组件来解决这个问题。使用了这个组件后,它会帮助自动完成键盘的自适应,通过偏移避免其他组件被键盘遮盖。

 

二、API

KeyboardAvoidingView组件提供了3个比较重要的属性,分别是behavior、contentContainerStyle、keyboardVerticalOffset。behavior译为行为,这里指键盘避免视图组件的位移焦点。contentContainerStyle是该组件内部视图的样式布局。keyboardVerticalOffset则是键盘的竖直偏移距离。如下:

//位移的参照焦点有三种:height:以高度为焦点  position:以位置为焦点  padding:以边距为焦点
behavior: PropTypes.oneOf([height, position, padding]),

//组件内容视图样式布局,只有采用‘ position’为焦点时,才会创建出这个内容视图
contentContainerStyle: ViewPropTypes.style,

//这是用户屏幕顶部与应用视图的距离,可以利用这个属性来补偿修正这段距离
keyboardVerticalOffset: PropTypes.number.isRequired,

KeyboardAvoidingView组件也提供了几个常用的方法,可以使用这几个方法手动来调整键盘的偏移。如下:

//键盘的相对高度
relativeKeyboardHeight(keyboardFrame: ScreenRect): number

//键盘改变时的回调
onKeyboardChange(event: ?KeyboardChangeEvent)

//键盘布局时的回调
onLayout(event: LayoutEvent)

//这个几个方法用到的对象如下
type Rect = {
  x: number,
  y: number,
  width: number,
  height: number,
};

type ScreenRect = {
  screenX: number,
  screenY: number,
  width: number,
  height: number,
};

type KeyboardChangeEvent = {
  startCoordinates?: ScreenRect, //起始位置
  endCoordinates: ScreenRect,    //终止位置 
  duration?: number,             //动画时间 
  easing?: string,          
};

type LayoutEvent = {
  nativeEvent: {
    layout: Rect,
  }
};

 

三、拓展

使用KeyboardAvoidingView组件时,可以搭配键盘组件Keyboard组件一起完成开发。键盘弹起和隐藏的过程,都可以使用键盘组件Keyboard进行监听。它提供了常用的几个监听名称和键盘相关数据,如下所示:

//监听名称
type KeyboardEventName =
     | keyboardWillShow
     | keyboardDidShow
     | keyboardWillHide
     | keyboardDidHide
     | keyboardWillChangeFrame
     | keyboardDidChangeFrame;

//键盘数据
type KeyboardEventData = {
     endCoordinates: { 
        width: number,
        height: number,
        screenX: number,
        screenY: number,},
    };    

提供的几个方法比较简单,如下所示:

//给键盘添加监听
addListener(eventName: KeyboardEventName, callback: KeyboardEventListener)

//给键盘移除监听
removeListener(eventName: KeyboardEventName, callback: Function)

//移除键盘所有监听
removeAllListeners(eventName: KeyboardEventName)

//关闭键盘
dismiss()

 

四、使用

现在使用KeyboardAvoidingView组件来调节输入框的位置,示例如下:

/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 * @flow
 */

import React, { Component } from react;

import {
    AppRegistry,
    StyleSheet,
    View,
    TextInput,
    Dimensions,
    Keyboard,
    KeyboardAvoidingView
} from react-native;

let {height} = Dimensions.get(window);

export default class ReactNativeDemo extends Component {

    componentWillMount() {
        this.keyboardDidShowListener = Keyboard.addListener(keyboardDidShow,(KeyboardEventData)=>{

            console.log(Keyboard Shown);
            console.log(KeyboardEventData.endCoordinates.screenY);

            // KeyboardAvoidingView实例的方法,可以在监听事件中调用
            // const avoidingView = this.refs.KeyboardAvoidingView;
            // avoidingView.onKeyboardChange(KeyboardChangeEvent);
            // avoidingView.onLayout(LayoutEvent);
            // avoidingView.relativeKeyboardHeight(keyboardFrame);
        });

        this.keyboardDidHideListener = Keyboard.addListener(keyboardDidHide, (KeyboardEventData)=>{

            console.log(Keyboard Hidden);
            console.log(KeyboardEventData.endCoordinates.screenY);

            // KeyboardAvoidingView实例的方法,可以在监听事件中调用
            // const avoidingView = this.refs.KeyboardAvoidingView;
            // avoidingView.onKeyboardChange(KeyboardChangeEvent);
            // avoidingView.onLayout(LayoutEvent);
            // avoidingView.relativeKeyboardHeight(keyboardFrame);
        });
    }

    componentWillUnmount() {
        this.keyboardDidShowListener.remove();
        this.keyboardDidHideListener.remove();
    }

    render() {
        return (
            <View style={[styles.flex,styles.bgColor]}>
                <KeyboardAvoidingView ref={KeyboardAvoidingView}
                                      behavior={position}
                                      keyboardVerticalOffset={10}
                                      contentContainerStyle={styles.avoidingView}>
                    <TextInput
                        style={styles.inputView}
                        placeholder=请输入关键字
                        placeholderTextColor="black"
                        returnKeyType=search
                        clearButtonMode=while-editing
                        enablesReturnKeyAutomatically={true}
                    />
                </KeyboardAvoidingView>
            </View>
        );
    }
}

const styles = StyleSheet.create({
    flex: {
        flex: 1
    },
    bgColor: {
      backgroundColor: white
    },
    center: {
        alignItems: center,
        justifyContent: center,
    },
    font: {
        fontSize: 30,
        color: purple,
        textAlign: center
    },
    avoidingView: {
        backgroundColor:#DDD
    },
    inputView:{
        height:100,
        borderWidth: 1,
        marginTop: height-111,
        marginRight:5,
        marginLeft: 5,
        paddingLeft: 5,
        borderColor:red,
        borderRadius: 4
    },
});

AppRegistry.registerComponent(ReactNativeDemo, () => ReactNativeDemo);

打印结果如下:

2020-01-02 17:22:55.793 [info][tid:com.facebook.react.javascript] Keyboard Shown
2020-01-02 17:22:55.794 [info][tid:com.facebook.react.JavaScript] 407
2020-01-02 17:23:05.852 [info][tid:com.facebook.react.JavaScript] Keyboard Shown
2020-01-02 17:23:05.853 [info][tid:com.facebook.react.JavaScript] 407
2020-01-02 17:23:08.470 [info][tid:com.facebook.react.JavaScript] Keyboard Hidden
2020-01-02 17:23:08.470 [info][tid:com.facebook.react.JavaScript] 667

截图结果如下:1图为初始状态、2图为不使用KeyboardAvoidingView组件时输入框被键盘遮盖、图3使用了KeyboardAvoidingView组件时不会遮盖正常使用。

技术图片 技术图片 技术图片

 

以上是关于ReactNative: 使用键盘避免视图KeyboardAvoidingView组件实现键盘自适应的主要内容,如果未能解决你的问题,请参考以下文章

在我的本机代码中,键盘避免视图不起作用

React Native:键盘在调整其视图高度时阻止多行文本输入

结合点击关闭键盘、键盘避免视图和提交按钮

避免 android 软键盘调整布局大小。或回调隐藏视图

键盘感知滚动视图Android问题

xml 隐藏/避免键盘在视图上显示