How to get 'Keyboard height before it opens' in React Native?
Asked Answered
F

2

8

Environment:

React-Native 0.60.4

Problem:

I'm developing chat app. The chat has emoji picker. Emoji picker must to has the same height that keyboard. I need to get the height of the keyboard before it opens. I tried to use keyboard listeners, but they give height after opening it. My ultimate goal is to do as in the picture. How do you do that?

My ultimate goal

Example:

import React, { useState, useEffect, createRef } from "react";
import {
  Keyboard,
  TextInput,
  View,
  EmitterSubscription,
  Button,
  KeyboardAvoidingView,
  StyleSheet
} from "react-native";

const APPROXIMATE_HEIGHT = 360;

const App = () => {
  let inputRef = createRef<TextInput>();

  const [visible, setVisible] = useState(false);
  const [height, setHeight] = useState(APPROXIMATE_HEIGHT);

  useEffect(() => {
    let keyboardDidShowListener: EmitterSubscription;

    keyboardDidShowListener = Keyboard.addListener(
      "keyboardDidShow",
      keyboardDidShow
    );

    return () => {
      if (keyboardDidShowListener) {
        keyboardDidShowListener.remove();
      }
    };
  });

  const keyboardDidShow = (e: any) => {
    setVisible(false);
    setHeight(e.endCoordinates.height); // sets the height after opening the keyboard
  };

  const openEmojiPicker = () => {
    Keyboard.dismiss();
    setVisible(true);
  };

  const openKeyboard = () => {
    setVisible(false);
    inputRef.current!.focus();
  };

  return (
    <KeyboardAvoidingView style={styles.container} behavior="height" enabled>
      <View style={styles.inputToolBar}>
        <Button
          title={visible ? "Open keyboard" : "Open emoji picker"}
          onPress={visible ? openKeyboard : openEmojiPicker}
        />
        <TextInput placeholder="test" ref={inputRef} />
      </View>
      <View style={[styles.emojiPicker, { height: visible ? height : 0 }]} />
    </KeyboardAvoidingView>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    position: "absolute",
    bottom: 0,
    left: 0,
    right: 0
  },
  inputToolBar: {
    flexDirection: "row"
  },
  emojiPicker: {
    backgroundColor: "red"
  }
});

export default App;
Fougere answered 11/8, 2019 at 6:42 Comment(2)
Try adding a riser to the constructor.Valenzuela
I don't understand what you meanAuraaural
R
1

I don't know a very clean way to do this, but you could show the keyboard, get the height, then replace the keyboard with your view.

Radack answered 13/8, 2019 at 19:1 Comment(5)
Yes, I agree with you, this is not the very clean way to do it. Didn't you realize the emoji picker in your chat app?Auraaural
Yes, but the primary use case was to first use the keyboard, then at some point during typing to then pull up the emoji or image picker. The case of pulling up the emoji or image picker before ever typing anything is pretty edge. We have a default value for the height of the emoji container based on if the user is on iOS or Android, and that default value is sometimes a few pixels off from the real keyboard height.It's overwritten once the keyboard is activated. It's a pretty unlikely edge case to pull up the emoji keyboard before the regular keyboard.Radack
You could even hide the emoji icon until the keyboard has been activated at least once. I also assume your users need to sign up or otherwise type a username in order to get into the app in the first place, during which you could save the keyboard height to storage.Radack
It's a good idea to save the keyboard height to storage when user sign in or sign up. How about landscape mode when text input has property disableFullscreenUI? Any ideas?Auraaural
We disabled landscape for our chat app, can't speak from experience. But it seems like you could save two values, one for regular and one for landscape mode.Radack
E
1

A very clever way to get height of keyboard before it opens, you can store keyboard height on Auth screen and store it to the local storage. That way you'll have keyboard height before it opens in chat screen.

Eyeopener answered 31/12, 2023 at 18:10 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.