kirillzyusko / react-native-keyboard-controller

Keyboard manager which works in identical way on both iOS and Android
https://kirillzyusko.github.io/react-native-keyboard-controller/
MIT License
1.38k stars 55 forks source link

KeyboardAvoidingView not working properly on Android #486

Closed alexyuan13 closed 2 days ago

alexyuan13 commented 6 days ago

Describe the bug In iOS: KeyboardAvoidingView works just as expected. In Android: KeyboardAvoidingView is not pushing screen the correct amount of space.

Code snippet I use the example code from the document and it's having the same issue in Android.

import React from "react";
import {
  Text,
  TextInput,
  TouchableOpacity,
  View,
  StyleSheet,
} from "react-native";
import { KeyboardAvoidingView } from "react-native-keyboard-controller";

export default function KeyboardAvoidingViewExample() {
  return (
    <KeyboardAvoidingView
      behavior={"padding"}
      contentContainerStyle={styles.container}
      keyboardVerticalOffset={100}
      style={styles.content}
    >
      <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>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  content: {
    flex: 1,
    maxHeight: 600,
  },
  heading: {
    fontSize: 36,
    marginBottom: 48,
    fontWeight: "600",
  },
  inner: {
    padding: 24,
    flex: 1,
    justifyContent: "space-between",
  },
  textInput: {
    height: 45,
    borderColor: "#000000",
    borderWidth: 1,
    borderRadius: 10,
    marginBottom: 36,
    paddingLeft: 10,
  },
  button: {
    marginTop: 12,
    height: 45,
    borderRadius: 10,
    backgroundColor: "rgb(40, 64, 147)",
    justifyContent: "center",
    alignItems: "center",
  },
  text: {
    fontWeight: "500",
    fontSize: 16,
    color: "white",
  },
});

To Reproduce

  1. Click on TextInput
  2. See the keyboard is pushing layout all the way up.

Expected behavior It should only push the layout up for the height of keyboard..

Screenshots KeyboardAvoidingView KeyboardAvoidingView2

Smartphone (please complete the following information):

Additional context I had some research and found there was some changes for useWindowDimensions in Android. I am guessing this only works for project that uses new architecture since the event emitter is targeted TurboModule. Do you have any suggestion for old architecture project as how should we handle this particular component? Thanks a lot for your efforts.

P.S I could manually change it to export { useWindowDimensions } from "react-native" but it doesn't fix the problem you mentioned in the PR though.

kirillzyusko commented 5 days ago

I am guessing this only works for project that uses new architecture since the event emitter is targeted TurboModule. Do you have any suggestion for old architecture project as how should we handle this particular component? Thanks a lot for your efforts.

This hook should work on both architectures.

I'm trying to reproduce the problem you mentioned 👀

kirillzyusko commented 5 days ago

Hey @alexyuan13

I just tested Android 15 and it works fine:

image

May I ask you to post a full reproduction example? For me it looks like windowSoftInputMode is changed during runtime (maybe to adjustPan?).

kirillzyusko commented 5 days ago

@alexyuan13 additionally you can try to disable KeyboardAvoidingView (<KeyboardAvoidingView enabled={false}) and check the behavior and share result here 👀

alexyuan13 commented 5 days ago

May I ask you to post a full reproduction example? For me it looks like windowSoftInputMode is changed during runtime (maybe to adjustPan?).

Thanks for replying so quick. You are right we did change winodwSoftInputMode to adjustNothing since we don't want android to adjust window position at all.

@alexyuan13 additionally you can try to disable KeyboardAvoidingView (<KeyboardAvoidingView enabled={false}) and check the behavior and share result here 👀

It won't push screen if I use enable={false}

kirillzyusko commented 4 days ago

@alexyuan13 okay, then I think it would be better to provide a reproduction example 🙏 That would simplify and speed up debugging significantly 👍

alexyuan13 commented 4 days ago

I think I found the issue. It works perfectly fine when starting the app first time. windowDidResize would trigger and the useWindowDimensions would return the correct dimensions. However, after you reload the app programmatically (pressing R in terminal for instance), the windowDidResize wouldn't get triggered again hence useWindowDimensions returning 0.

I guess this is not really a bug and happy to close the issue. Thanks so much for taking time look into it.

I've created an expo project and can be reproduced. keyboard-avoiding-view-example

kirillzyusko commented 3 days ago

@alexyuan13 amazing! Thank you for diving in the code and such a detailed explanation!

Could you please try to use https://github.com/kirillzyusko/react-native-keyboard-controller/pull/492 and see if it fixes the problem? In my example app pressing R two times triggers a crash (don't know why), but the problem you are talking about indeed exist and I fixed it in a linked PR 👀

rodnoycry commented 3 days ago

Hi, I wanted to let you know, that we have pretty much same issue - on initial android app start component moves the screen to correct height, but after hot reloads it starts to break, and screen starts to move much higher (about keyboard height)

Right now we are limited in resources to make new builds, but if we would have opportunity - we will test this PR and give feedback

kirillzyusko commented 2 days ago

I've published 1.12.5 and I think the problem has been fixed there!

If not - let me know and I'll re-open this issue!

alexyuan13 commented 3 hours ago

I've published 1.12.5 and I think the problem has been fixed there!

If not - let me know and I'll re-open this issue!

I can confirm it fixes the issue! Thanks a lot @kirillzyusko