zoukankan      html  css  js  c++  java
  • 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,
       number,
      height: number,
    };
    
    type ScreenRect = {
      screenX: number,
      screenY: number,
       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: { 
             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组件时不会遮盖正常使用。

      

  • 相关阅读:
    Dapper使用
    EF5.X Code First表关联与延迟加载
    EF Code First 学习笔记:关系
    Entity Framework
    MVC3+EF4.1学习系列(五)----- EF查找导航属性的几种方式
    QML与C++混合编程
    如何将信号从javascript发射到qml
    qt quick中qml编程语言
    PyQt 5信号与槽的几种高级玩法
    静态编译OpenSSL并整合到Qt
  • 原文地址:https://www.cnblogs.com/XYQ-208910/p/12134156.html
Copyright © 2011-2022 走看看