Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

KeyboardAvoidingView doesn't work on Android #650

Closed
gkassym opened this issue Oct 22, 2024 · 11 comments
Closed

KeyboardAvoidingView doesn't work on Android #650

gkassym opened this issue Oct 22, 2024 · 11 comments
Assignees
Labels
🤖 android Android specific 🐛 bug Something isn't working

Comments

@gkassym
Copy link

gkassym commented Oct 22, 2024

KeyboardAvoidingView doesn't work on Android

I installed the react-native-keyboard-controller library and ran pod install. I wrapped the root component with KeyboardProvider, and everything works as expected on iOS. However, on Android, it doesn't work at all. I also tried using KeyboardAwareScrollView, but encountered the same issue—it doesn't work. Then, I attempted to use KeyboardEvents, but the listener callback doesn't trigger when the keyboard opens or closes. As mentioned, iOS works perfectly. I performed a clean build, cleared the Android/app build, cleaned the Gradle files, and removed node_modules, but none of these steps resolved the problem.

I believe the native code wasn't installed correctly. Any ideas?

Code snippet

export function MessagingScreen(): JSX.Element {
  useEffect(() => {
    const show = KeyboardEvents.addListener('keyboardWillShow', (e) => {
      console.log('keyboardWillShow---------------', e); // <- doesn't trigger
    });

    return () => {
      show.remove();
    };
  }, []);

  return (
    <KeyboardAvoidingView
      contentContainerStyle={styles.container}
      style={styles.content}
      behavior="padding"
      keyboardVerticalOffset={400}>
      <View style={styles.inner}>
        <Text style={styles.heading}>Header</Text>
        <View>
          <TextInput placeholder="Username" style={styles.textInput} />
          <TextInput placeholder="Password" style={styles.textInput} />
        </View>
        <TouchableOpacity style={styles.button}>
          <Text style={styles.text}>Submit</Text>
        </TouchableOpacity>
      </View>
    </KeyboardAvoidingView>
  );
}

Screenshots

Screen.Recording.2024-10-22.at.10.51.59.mov

Smartphone (please complete the following information):

RN version: 0.75.3
RN architecture: Old
JS engine: Hermes
Library version: 1.14.2
React-native-reanimated: 3.16.1

Additional context
Add any other context about the problem here.

@kirillzyusko
Copy link
Owner

@gkassym do you use react-native-screens/native-stack by any chance? If yes, then which version of react-native-screens are you using (which version is specified in .lock file)? Do you use navigationBar* properties from native-stack by any chance?

@kirillzyusko kirillzyusko added 🐛 bug Something isn't working 🤖 android Android specific labels Oct 22, 2024
@gkassym
Copy link
Author

gkassym commented Oct 22, 2024

Yes, i use:

  • react-native-screens: "^3.34.0"
  • @react-navigation/native: "^6.1.4"
  • @react-navigation/native-stack: "^6.9.10"
  • @react-navigation/stack: "^6.3.16"
  • pnpm: "9.10.0"
  • node: "v18.20.2"

Also i noticed this warning:
Deprecated Gradle features were used in this build, making it incompatible with Gradle 9.0.
Could this have any impact?

@kirillzyusko
Copy link
Owner

Also i noticed this warning:
Deprecated Gradle features were used in this build, making it incompatible with Gradle 9.0.
Could this have any impact?

I don't think so 🙂

Can you try to apply a patch from software-mansion/react-native-screens#2301 and re-build the project? It may solve the problem 🙂

@gkassym
Copy link
Author

gkassym commented Oct 23, 2024

I applied the patch you recommended. It works. 👍

@gkassym
Copy link
Author

gkassym commented Oct 23, 2024

But in the Android app there is a weird line at the top. If I do KeyboardProvider enabled={false} it disappears. What is it?
Screenshot 2024-10-23 at 15 32 12

@kirillzyusko
Copy link
Owner

But in the Android app there is a weird line at the top. If I do KeyboardProvider enabled={false} it disappears. What is it?

@gkassym did you try to add statusBarTranslucent property to KeyboardProvider? Does it solve the problem?

@gkassym
Copy link
Author

gkassym commented Oct 23, 2024

Nice 🔥 statusBarTranslucent works.

Another thing I noticed is that the keyboard opens first in Android and then it moves the text input. Have you seen anything like this?

Screen.Recording.2024-10-23.at.16.01.15.mov

@kirillzyusko
Copy link
Owner

Yes @gkassym

It happens if you animate height/padding or any other non-UI props on Android. If you want to have a perfect animation synchronization then you can use https://github.com/kirillzyusko/react-native-keyboard-controller/blob/main/example/src/screens/Examples/ReanimatedChat/index.tsx as a reference - in this example I'm animating translateY and it works frame-in-frame 👀

I believe I answered on your questions and the conversation goes into a different direction - can I close this issue?
If you encounter any other problem don't hesitate to open a new issue - I will be happy to help and guide you 😊

@gkassym
Copy link
Author

gkassym commented Oct 23, 2024

Sure, thanks. Happy Coding!!!

kirillzyusko added a commit that referenced this issue Feb 24, 2025
…ew` (#830)

## 📜 Description

Added new `behavior="translate-with-padding"` for
`KeyboardAvoidingView`.

## 💡 Motivation and Context

The new mode ideally fits for chat-like applications and has very good
performance.

The implementation was mostly inspired by
[WindowInsetsAnimation](https://github.com/android/user-interface-samples/tree/main/WindowInsetsAnimation)
sample app. However when I tried to replace `translateY` to `0` and
apply `paddingBottom` which is equal to previous `translateY` I had
flashes on Android (mostly because of nature of Android - transform
properties (e.g., `translateY`) only trigger a **repaint** (no _reflow_)
and are applied **immediately**. Changes to **layout** properties like
**padding** force the Android rendering system to recalculate layout
(**reflow**), which can take an extra frame to resolve). So instead of
switching those properties I decided to keep `translateY` and add
`paddingTop` (in the end of animation to resize the container).

Since we change `paddingTop` only in the beginning or in the end of
animation the transition is unbelievable smooth, because we trigger
layout re-calculation only once (so in terms of complexity new approach
is `O(1)` vs `O(n)`).

Closes
#719 (comment)
software-mansion/react-native-reanimated#6854
#650 (comment)

## 🔢 Things to do
- write e2e tests for chat FlatList example screen (to cover new
functionality with e2e tests);
- update documentation page with detailed explanation of modes and when
to use each of them.

## 📢 Changelog

<!-- High level overview of important changes -->
<!-- For example: fixed status bar manipulation; added new types
declarations; -->
<!-- If your changes don't affect one of platform/language below - then
remove this platform/language -->

### JS

- added new `"translate-with-padding"` behavior for
`KeyboardAvoidingView`
- added `useTranslateAnimation` hook;
- integrate `useTranslateAnimation` with `"translate-with-padding"`;
- update example app to more performant implementation;

### Docs
- mention new behavior;

## 🤔 How Has This Been Tested?

Tested both paper and fabric on:
- iPhone 15 Pro (iOS 17.5);
- Medium phone (API 35).

## 📸 Screenshots (if appropriate):

### Paper

|Android|iOS|
|--------|---|
|<video
src="https://github.com/user-attachments/assets/f8d35138-77ae-432e-a95b-97104a01b4fe">|<video
src="https://github.com/user-attachments/assets/93db0cdb-4ef4-4fb0-8cd4-9ada0312ff7d">|

### Fabric

|Android|iOS|
|--------|---|
|<video
src="https://github.com/user-attachments/assets/e2398edc-d6c0-41e8-8fdc-eb95e7741f74">|<video
src="https://github.com/user-attachments/assets/379567d3-5d7a-482c-81af-ab359356a11c">|

## 📝 Checklist

- [x] CI successfully passed
- [x] I added new mocks and corresponding unit-tests if library API was
changed
@kirillzyusko
Copy link
Owner

@gkassym I added new behavior="translate-with-padding" for KeyboardAvoidingView (see #830) - it should resolve your issue mentioned in #650 (comment) 👀

New mode is available in 1.16.5 🚀

@gkassym
Copy link
Author

gkassym commented Feb 25, 2025

Hi @kirillzyusko, wow, nice. I will check. Thanks 🔥

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🤖 android Android specific 🐛 bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants