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

KeyboardAwareScrollView on android is not as smooth as ios #719

Open
caothuyen opened this issue Dec 4, 2024 · 13 comments
Open

KeyboardAwareScrollView on android is not as smooth as ios #719

caothuyen opened this issue Dec 4, 2024 · 13 comments
Assignees
Labels
🤖 android Android specific KeyboardAwareScrollView 📜 Anything related to KeyboardAwareScrollView component repro provided Issue contains reproduction repository/code

Comments

@caothuyen
Copy link

caothuyen commented Dec 4, 2024

Describe the bug
When the keyboard opens, the content below is pushed up, not as smoothly as on iOS.

Code snippet

function LoginScreen() {
  return (
    <View style={styles.container}>
      <View style={styles.background}>
        <LinearGradient
          colors={["#114395", "#195DCE", "#1F6BF2", "#0A89E2", "#fff"]}
          locations={[0, 0.135, 0.36, 0.45, 0.625]}
          style={[styles.background, styles.backgroundLinear]}
        />
        <LogoLine style={[styles.logoLine, styles.background]} />
        <NetworkLine style={[styles.networkLine, styles.background]} />
      </View>

      <KeyboardAwareScrollView style={styles.scrollView} showsVerticalScrollIndicator={false}>
        <View style={styles.content}>
          <Image source={require("assets/images/icon.png")} style={styles.logo} fadeDuration={0} />
          <Text style={styles.title}>Chào mừng đến với Quốc Duy</Text>
          <RenderForm />
          <TextInput style={{ height: 48, borderWidth: 1, borderColor: "red" }} placeholder="press input" />
          <TextInput style={{ height: 48, borderWidth: 1, borderColor: "red" }} placeholder="press input" />
          <TextInput style={{ height: 48, borderWidth: 1, borderColor: "red" }} placeholder="press input" />
        </View>
      </KeyboardAwareScrollView>
    </View>
  );
}

Expected behavior
On android can be as smooth as ios

Screenshots

Screen.Recording.2024-12-04.at.09.46.42.mov
Screen.Recording.2024-12-04.at.09.47.07.mov

I tested on real device and production environment but still not effective

  • Desktop OS: MacOS 15.1.1
  • Device: iPhone 14 Pro Max and Android pixel 6 pro
  • OS: iOS 17.5 and android 12
  • RN version: 0.76.3
  • RN architecture: paper/fabric
  • JS engine: Hermes
  • Library version: 1.14.5
@caothuyen
Copy link
Author

caothuyen commented Dec 4, 2024

This code in RenderForm

function RenderForm() {
  const handleLogin = async (username, password) => {
    await Login(username, password);
  };

  return (
    <View style={styles.formContainer}>
      <FieldWrapper label="Tên đăng nhập">
        <Input iconLeft="fa-user" />
      </FieldWrapper>
      <FieldWrapper label="Mật khẩu">
        <Input iconLeft="fa-key" iconRight={<RenderShowPassword />} secureTextEntry />
      </FieldWrapper>
      <FieldWrapper label="Tên đăng nhập">
        <Input iconLeft="fa-user" />
      </FieldWrapper>
      <FieldWrapper label="Tên đăng nhập">
        <Input iconLeft="fa-user" />
      </FieldWrapper>
      <FieldWrapper label="Tên đăng nhập">
        <Input iconLeft="fa-user" />
      </FieldWrapper>
      <FieldWrapper label="Tên đăng nhập">
        <Input iconLeft="fa-user" />
      </FieldWrapper>
      <FieldWrapper label="Tên đăng nhập">
        <Input iconLeft="fa-user" />
      </FieldWrapper>
      <FieldWrapper label="Tên đăng nhập">
        <Input iconLeft="fa-user" />
      </FieldWrapper>
      <AnimPress onPress={() => handleLogin("*****", "*****")}>
        <View style={styles.buttonSubmit}>
          <Text style={styles.buttonSubmitText}>Đăng nhập</Text>
        </View>
      </AnimPress>
    </View>
  );
}

const FieldWrapper = memo(({ children, label }) => (
  <View style={styles.fieldWrapper}>
    <Text style={styles.fieldLabel}>{label}</Text>
    {children}
  </View>
));

const RenderShowPassword = memo(() => {
  return (
    <TouchableOpacity onPress={() => {}} activeOpacity={0.8}>
      <FaIcon icon="fa-eye" size={16} color={colors.dark_gray} />
    </TouchableOpacity>
  );
});

@kirillzyusko
Copy link
Owner

Hi @caothuyen

This is how animation looks on my Pixel 7 Pro (Android 15) - tested in example app:

telegram-cloud-document-2-5368776602526179445.mp4

I don't have any missing frames - would you mind to create a reproducible example (including all styles) so that I can copy/paste it into my example app?

@kirillzyusko kirillzyusko added 🤖 android Android specific KeyboardAwareScrollView 📜 Anything related to KeyboardAwareScrollView component labels Dec 4, 2024
@caothuyen
Copy link
Author

caothuyen commented Dec 5, 2024

Here is the example source code: https://github.com/caothuyen/example.git the page I recorded in the video is located at src/screens/User/Login

@kirillzyusko kirillzyusko added the repro provided Issue contains reproduction repository/code label Dec 13, 2024
@kirillzyusko
Copy link
Owner

Thanks @caothuyen for a reproduction! Checking it today 👀

@kirillzyusko
Copy link
Owner

@caothuyen getting this:

> Task :expo-updates:kspDebugKotlin FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':expo-updates:kspDebugKotlin'.
> java.io.StreamCorruptedException: unexpected EOF in middle of data block

When try to build the app. Any ideas why?..

@shuo-hiwintech
Copy link

shuo-hiwintech commented Dec 24, 2024

Code to run this example on Android:

The actual result is very choppy and jerky up and down on Android, very flowy on IOS.

"react-native": "0.76.2".
"react-native-keyboard-controller":"^1.14.5",
"react-native-reanimated":"^3.16.2",

@kirillzyusko
Copy link
Owner

@shuo-hiwintech which Android version do you use? Which RN architecture do you use? Can you attach a video? Is it reproducible in emulator?

telegram-cloud-document-2-5426846321304701690.mp4

This is how it looks on my Pixel 7 Pro (Android 15, REA 3.16.1, paper/old architecture) 👀

@shuo-hiwintech
Copy link

@shuo-hiwintech which Android version do you use? Which RN architecture do you use? Can you attach a video? Is it reproducible in emulator?

telegram-cloud-document-2-5426846321304701690.mp4
This is how it looks on my Pixel 7 Pro (Android 15, REA 3.16.1, paper/old architecture) 👀

Thanks for the quick response, I'm using your library in another project with a new non-RN architecture and it's running great.

The status of my new project:

"react-native": "0.76.2", yes I'm using the new RN architecture.

Android real machine information:
REDMI K80
Android version 15

Screenrecorder-2024-12-24-19-21-46-176.mp4

(Shaky video recording, recorded at 90 fps)

@shuo-hiwintech
Copy link

@shuo-hiwintech which Android version do you use? Which RN architecture do you use? Can you attach a video? Is it reproducible in emulator?

telegram-cloud-document-2-5426846321304701690.mp4
This is how it looks on my Pixel 7 Pro (Android 15, REA 3.16.1, paper/old architecture) 👀

My code:

import {FlatList, Text, View} from 'react-native';
import {useKeyboardHandler} from 'react-native-keyboard-controller';
import Animated, {
  useAnimatedStyle,
  useSharedValue,
} from 'react-native-reanimated';

import Input from '@/components/Input';

const useGradualAnimation = () => {
  const height = useSharedValue(0);

  useKeyboardHandler(
    {
      onMove: e => {
        'worklet';

        height.value = e.height;
      },
      onEnd: e => {
        'worklet';

        height.value = e.height;
      },
    },
    [],
  );

  return {height};
};

const Home = () => {
  const {height} = useGradualAnimation();

  const fakeView = useAnimatedStyle(
    () => ({
      height: Math.abs(height.value),
    }),
    [],
  );

  return (
    <View style={{flex: 1}}>
      <FlatList
        inverted
        data={Array.from({length: 50})}
        initialNumToRender={15}
        renderItem={({_, index}) => {
          return (
            <View>
              <Text style={{color: 'pink'}}>{index}</Text>
            </View>
          );
        }}
      />

      <View
        style={{
          backgroundColor: '#ec7373',
          padding: 10,
        }}>
        <Input placeholder={' leave your comment here.'} />
      </View>

      <Animated.View style={fakeView} />
    </View>
  );
};

export default Home;

@shuo-hiwintech
Copy link

@shuo-hiwintech which Android version do you use? Which RN architecture do you use? Can you attach a video? Is it reproducible in emulator?

telegram-cloud-document-2-5426846321304701690.mp4
This is how it looks on my Pixel 7 Pro (Android 15, REA 3.16.1, paper/old architecture) 👀

Unfortunately, it's not possible to replicate this on an android emulator, I suspect it should be possible to replicate it on a real android machine. : (

@kirillzyusko
Copy link
Owner

@shuo-hiwintech well, I think I encounter a similar issue, when performance on a new architecture is not as great as on old architecture. The only one thing that I discovered is that only non-UI props (such as height) are problematic. If you animate translateY then everything works well.

Maybe it's because of not very optimized ShadowTree traversal on reanimated side (but honestly I don't know a root cause, so it's only my guesses). Let me run fabric example on my devices and get back to you!

@kirillzyusko
Copy link
Owner

I opened an issue in reanimated: software-mansion/react-native-reanimated#6854

I don't think I can fix it in keyboard-controller code, so let's see what reanimated team thinks about it 🙂

@shuo-hiwintech
Copy link

I opened an issue in reanimated: software-mansion/react-native-reanimated#6854

I don't think I can fix it in keyboard-controller code, so let's see what reanimated team thinks about it 🙂

Thank you for your conscientiousness and let's hope that good things will come~

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🤖 android Android specific KeyboardAwareScrollView 📜 Anything related to KeyboardAwareScrollView component repro provided Issue contains reproduction repository/code
Projects
None yet
Development

No branches or pull requests

3 participants