UNPKG

react-native-keyboard-aware-view

Version:

A simple React Native View component that resizes composite children views inside itself when the keyboard appears. You can implement your own ScrollView, ListView, Multiple Views etc... inside the View and set your own view to 'flex: 1'.

147 lines (124 loc) 4.08 kB
'use strict'; import React, { Component } from 'react'; import { Dimensions, Animated, View, ScrollView, Keyboard, Platform, } from 'react-native'; var {width, height} = Dimensions.get('window'); import dismissKeyboard from 'react-native/Libraries/Utilities/dismissKeyboard' class CoreKeyboardAwareView extends React.Component { constructor(props) { super(props); this.state = { height: new Animated.Value(0) } this.debug = false; } componentDidMount() { Keyboard.addListener('keyboardWillShow', this.onKeyboardWillShow.bind(this)) Keyboard.addListener('keyboardWillHide', this.onKeyboardWillHide.bind(this)) } componentWillUnmount() { } debugLog() { if (this.debug) { console.log.apply(this, arguments); } } onKeyboardWillShow(e) { var endY = e.endCoordinates.screenY var startY = e.startCoordinates.screenY this.debugLog(e); requestAnimationFrame(() => { if (this.outerView == null) return; this.outerView.measure((ox, oy, width, height, px, py) => { this.debugLog(ox, oy, px, py); // target scrollView height should be : // remaining height OR outerView height // = screen height - keyboard height OR outerView height var remainScreenMaxHeight = endY - py; var outerViewMaxHeight = height; var maxHeight = remainScreenMaxHeight; if (maxHeight > outerViewMaxHeight) { maxHeight = outerViewMaxHeight; } Animated.timing( this.state.height, { toValue: maxHeight, duration: this.props.animated ? 200 : 0, } ).start(); this.debugLog("InnerView height should be ..." + maxHeight, remainScreenMaxHeight, outerViewMaxHeight); //requestAnimationFrame(() => { // this.innerView.measure((ox, oy, width, height, px, py) => { // this.debugLog("And it is... " + height); // }) //}) }); }) } onKeyboardWillHide(e) { var endY = e.endCoordinates.screenY var startY = e.startCoordinates.screenY this.debugLog(e); requestAnimationFrame(() => { if (this.outerView == null) return; this.outerView.measure((ox, oy, width, height, px, py) => { this.debugLog(ox, oy, px, py); // target scrollView height should be : // remaining height OR outerView height // = screen height - keyboard height OR outerView height var remainScreenMaxHeight = endY; var outerViewMaxHeight = height; var maxHeight = remainScreenMaxHeight; if (maxHeight > outerViewMaxHeight) { maxHeight = outerViewMaxHeight; } Animated.timing( this.state.height, { toValue: maxHeight, duration: this.props.animated ? 200 : 0, } ).start(); this.debugLog("ScrollView height should be ..." + maxHeight); }); }) } render() { return ( <View ref={(ref) => {this.outerView = ref;}} style={[{flex: 1}, this.props.style]} onLayout={(e) => { var {x, y, width, height} = e.nativeEvent.layout; Animated.timing( this.state.height, { toValue: height, duration: 0, } ).start(); if (Platform.OS === 'ios') { if (this.props.doNotForceDismissKeyboardWhenLayoutChanges === false) { dismissKeyboard(); } } }}> <Animated.View ref={(ref) => {this.innerView = ref;}} style={[{height: this.state.height}, this.props.innerViewStyle]} onLayout={(e) => { var {x, y, width, height} = e.nativeEvent.layout; } }> {this.props.children} </Animated.View> </View> ) } } module.exports = CoreKeyboardAwareView;