Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to handle back button when TexInput is focused

This is a react-native question for Android.

How can I handle the back button in Android when a TextInput is focused? BackHandler.addEventListener('hardwareBackPress'. () => {}) does not catch any event if TextInput is focused. It automatically dismisses the keyboard.

(Actually what I am trying to achieve is to remove the cursor when Back Button is pressed and the keyboard is dismissed)

You can play with this expo snack to understand what I am talking about:

like image 880
Francisco Sarmento Avatar asked Nov 07 '18 13:11

Francisco Sarmento


3 Answers

I believe that is the correct behavior, but to make what you want, you may detect the keyboard itself hiding instead by using Keyboard (docs at https://facebook.github.io/react-native/docs/keyboard)

import * as React from 'react';
import { Keyboard } from 'react-native';

class MyComponent extends React.Component {
  componentDidMount() {
      this.keyboardDidHideListener = Keyboard.addListener('keyboardDidHide', this.keyboardDidHide);
  }

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

  keyboardDidHide = () => {
      this.input.blur();
  };

    //Rest of component...

}

I prefer this method than using the onKeyPress event from TextInput because onKeyPress won't read hardware keyboard back presses, so if the user has a device with hardware back buttons, like some Android devices have, the onKeyPress won't work, this provides a more consistent experience.

like image 196
Danilo Avatar answered Sep 28 '22 01:09

Danilo


@Danilo answer does work, but it has to be applied to all text inputs. I ended up using Danilo's solution with a small twist.

Keyboard.dismiss() does blur any active TextInput, so on keyboardDidHide event I just call Keyboard.dismiss() (although the keyboard just got dismissed by pressing back button). I just need to add this to my main component.

import * as React from 'react';
import { Keyboard } from 'react-native';

class MyComponent extends React.Component {
  componentDidMount() {
      this.keyboardDidHideListener = Keyboard.addListener('keyboardDidHide', this.keyboardDidHide);
  }

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

  keyboardDidHide = () => {
      Keyboard.dismiss();
  };

    //Rest of component...

}

You can teste this solution in this expo snack.

In case your app has multiple TextInputs that onSubmitEditing focus the next TextInput, this is how I made it work:

  ...

  keyboardDidHide = () => {
      this.keyboardTimeout = setTimeout(() => Keyboard.dismiss(), 300)
  };

  keyboardDidShow = () => {
      clearTimeout(this.keyboardTimeout)
  };

  ...
like image 34
Francisco Sarmento Avatar answered Sep 28 '22 00:09

Francisco Sarmento


You'd handle it on the TextInput itself instead of using a BackHandler. You can do this via the onKeyPress prop

constructor(props){
  super(props)
  this.inputRef = React.createRef()
}

<TextInput
  onKeyPress={({ nativeEvent }) => {
    if(nativeEvent.key === 'Backspace'){
      //your code
      // if you want to remove focus then you can use a ref
      Keyboard.dismiss();
      this.inputRef.blur()
    }
  }}
  ref={this.inputRef}
/>

Also it's important to note that on Android this event will only fire on the software keyboard, so if you're running on an emulator and use the backspace key on your computer's keyboard this will not work.

like image 37
Robbie Milejczak Avatar answered Sep 28 '22 02:09

Robbie Milejczak