Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get a height of a Keyboard in React-Native?

I am using React-Navigation in my app and the app consists of StackNavigator with multiple screens, some screens of which have TextInput with autoFocus={true}

Problem: on these screens when the component renders, the height of the screen is being set in the constructor:

constructor(props) {     super(props);     this.state = {          height: Dimensions.get('window').height,     }; } 

But, since the autoFocus of TextInput is true, the keyboard on this screen pops-up on the screen almost instantly after the render, causing the component to re-render due to the eventListener that is added to Keyboard in componentWillMount:

 componentWillMount() {     this.keyboardWillShowListener = Keyboard.addListener(         "keyboardWillShow",         this.keyboardWillShow.bind(this)     ); }  keyboardWillShow(e) {     this.setState({         height:             Dimensions.get("window").height * 0.9 - e.endCoordinates.height     });     LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut); } 

This affects the performance and I would like to avoid the unnecessary re-renders.

Questions:
1. Is it possible to set the dynamic height (depending on the device) of the Keyboard in React-Navigation's ScreenProps?
2. Is it possible to do the same with React-Navigation's state.params?
3. Is there any other way to solve this problem, apart from applying KeyboardAvoidingView or this module ?

like image 846
Eduard Avatar asked Oct 05 '17 13:10

Eduard


People also ask

How do I get the keyboard height in React Native?

addListener('keyboardDidHide', this. _keyboardDidHide); Add autoFocus to e-mail / phone number / any other "first" TextInput on the page, so that when the screen loads, the Keyboard pops-up. Dimensions is an API of React-Native, do not forget to import it just like you import any React-Native component.

What is keyboardVerticalOffset in React Native?

keyboardVerticalOffset ​ This is the distance between the top of the user screen and the react native view, may be non-zero in some use cases.


2 Answers

This is what I did:

If the app has "Authorization / Log-in / Sign-up screen" then:

  1. In componentWillMount add KeyboardListeners as explained here:

    this.keyboardDidShowListener = Keyboard.addListener('keyboardDidShow', this._keyboardDidShow); this.keyboardDidHideListener = Keyboard.addListener('keyboardDidHide', this._keyboardDidHide); 
  2. Add autoFocus to e-mail / phone number / any other "first" TextInput on the page, so that when the screen loads, the Keyboard pops-up.

  3. In _keyboardDidShow function, that is used as a KeyboardListener, do the follows:

    _keyboardDidShow(e) {     this.props.navigation.setParams({         keyboardHeight: e.endCoordinates.height,         normalHeight: Dimensions.get('window').height,          shortHeight: Dimensions.get('window').height - e.endCoordinates.height,      });  } 

    Dimensions is an API of React-Native, do not forget to import it just like you import any React-Native component.

  4. After that, while redirecting to the next page, pass these params and do not forget to keep on passing them to other screens in order not to lose this data:

    this.props.navigation.navigate('pageName', { params: this.props.navigation.state.params }); 
like image 196
Eduard Avatar answered Oct 15 '22 23:10

Eduard


I also needed a hook for it, so that is how I get the height of the keyboard (largely inspired by the other answer), the code example is in TypeScript:

import { useEffect, useState } from 'react'; import { Keyboard, KeyboardEvent } from 'react-native';  export const useKeyboard = () => {   const [keyboardHeight, setKeyboardHeight] = useState(0);    function onKeyboardDidShow(e: KeyboardEvent) { // Remove type here if not using TypeScript     setKeyboardHeight(e.endCoordinates.height);   }    function onKeyboardDidHide() {     setKeyboardHeight(0);   }    useEffect(() => {     const showSubscription = Keyboard.addListener('keyboardDidShow', onKeyboardDidShow);     const hideSubscription = Keyboard.addListener('keyboardDidHide', onKeyboardDidHide);     return () => {       showSubscription.remove();       hideSubscription.remove();     };   }, []);    return keyboardHeight; };  

then in your component:

  const keyboardHeight = useKeyboard();   console.log(keyboardHeight); 
like image 38
Kevin Amiranoff Avatar answered Oct 16 '22 00:10

Kevin Amiranoff