unable to scroll in scrollView
Asked Answered
A

6

2

I have a screen where I type in the input field and get search results accordingly. The list is rendered within a ScrollView but it still doesn't let me scroll when the keypad is open (in Android ).

How can I fix this?

  return (
    <>
      {addressesFound.length > 0 ? (
        <ScrollView
          style={styles.searchResultsContainer}
          keyboardShouldPersistTaps={'always'}
          keyboardDismissMode={'on-drag'}>
          {addressesFound.map((addressDetails: addressDetailsType) => {
            return (
              <View
                key={addressDetails.placeName}
                style={styles.resultContainer}>
                <Text
                  style={styles.text}>
                  {addressDetails.placeName}
                </Text>
              </View>
            );
          })}
        </ScrollView>
      ) : null}
    </>
  );
};
const styles = StyleSheet.create({
  searchResultsContainer: {
    width: moderateScale(400),
    paddingHorizontal: moderateScale(50),
    paddingRight: moderateScale(65),
    marginTop: moderateScale(10),
   flex:1,
  },
  resultContainer: {
    marginTop: moderateScale(10),
    borderBottomWidth: 1,
    borderBottomColor: 'grey',
  },
  text: {
    fontSize: moderateScale(15),
  },
});

enter image description here

I have already tried adding nestedScrollEnabled={true} but it makes no difference.

This is where the above mentioned component is called:

        <View style={styles.dropdown}>
          <LocationsFound
            addressesFound={locations.addressesFoundList} />
....
  dropdown: {
    position: 'absolute',
    top: moderateScale(215),
    zIndex: moderateScale(10),
    backgroundColor: '#fff',
    flex: 1,
  },

I tried adding height: 80% to dropdown. This makes it possible to scroll a bit. However, when the keypad is open I can scroll but not to the end. If I add height: 100%, I am not able to scroll at all.

Administer answered 16/8, 2020 at 13:5 Comment(0)
H
0

I made an expo snack for your problem and examined it. I think I solved it. take a look at it:

This is the link to the expo snack

To describe about it:

As I found out, your problem was that the ScrollView wasn't changing height in any situations, even by giving more height or giving paddingBottom.

so I wrapped the ScrollView in a View tag and gave this styling to it:

scrollViewWrapper: {
     width: '100%',
     minHeight: '100%',
     paddingBottom: 1.3*keyboardHeight
 }

In this styling, you see parameter keyboardHeight, which is a state that I'm setting in the componentDidMount with below codes:

import {Keyboard} from 'react-native';
 
state = {
  keyboardHeight: 0,
}

componentDidMount() {
this.keyboardDidShowListener = Keyboard.addListener(
  'keyboardDidShow',
  this._keyboardDidShow
);
this.keyboardDidHideListener = Keyboard.addListener(
  'keyboardDidHide',
  this._keyboardDidHide
 );
}
_keyboardDidShow = (e) => {
  this.setState({
    keyboardHeight: e.endCoordinates.height,
  });
};

I have to mention that you cannot move the style of paddingBottom: 1.3*keyboardHeight outside of the class component and place it in styles object, because the keyboardHeight is a state, it can be known just inside the component.

I suggest you to take a look at my code in expo snack to understand my descriptions better.

I hope this solve your problem.

Edit for functional components

use below code to detect keyboard height while writing functional components:

const [keyboardHeight, setKeyboardHeight] = useState(0)
const [scrollViewVisibility, setScrollViewVisibility] = useState(false)
useEffect(() => {
  Keyboard.addListener("keyboardDidShow", _keyboardDidShow);

  // cleanup function
  return () => {
    Keyboard.removeListener("keyboardDidShow", _keyboardDidShow);
  };
}, []);
const _keyboardDidShow = (e) => {
  console.log("============in keyboardDidShow")
  setKeyboardHeight(e.endCoordinates.height)
};

I edited the expo snack too. you can take a look at it to see a working example.

Hauser answered 20/8, 2020 at 13:46 Comment(8)
Could you modify it according to the functional components? For state we can use useState and for componentDidMount we can use useEffect but I am unable to figure out how to replace this.keyboardDidShowListener in my case.Administer
Also, I can't really evaluate your snack expo since its a bit different than mine. In my case, once the list is displayed, the keyboard is still open. However, in your expo, the keyboard disappears when I search for the list is displayed.Administer
@Jnl I modified the expo snack and wrote an edit for this solution. check it out. about the difference between my code and yours, yes, there are some differences but I think you have checked my snack on the web mode, check it on iPhone mode. You'll see that it's so similar to yours.Hauser
This kinda works if I add an additional height:'80%' to my dropdown Viewwhich is the parent of the whole LocationsFound list component. Is it possible to move the height styling within LocationsFound as well? Such that it can automatically be calculated on different screens.Administer
My LocationFound is like your expo, minus the container View & TextInput at the very top. If I don't add the height to dropdown separately, it doesn't scroll.Administer
@Jnl If your LocationsFound component is like my expo snack, so you can wrap your whole component in a <View></View> tag (inside the component), then give it the paddingBottom: 1.3*keyboardHeight like my expo snack. I think if you do this, there will be no need to add a keyboardHeight related height to the dropdown View. If you make an expo snack of your problem, I can help you more.Hauser
I have already given the keyboardHeight as you suggest but it still requires an additional height. Unfortunately, the searching feature is too complex but I will still try to make an expoAdminister
@Jnl we do not need the searching method and codes. You can remove all lines that make up your list in the ScrollView and make it as simple as possible, like mine. keep me posted when you're done.Hauser
B
1

I think that if your ScrollView contents are smaller than the screen, it won't scroll. So you can try making height: "150%" or something like that or add in an empty view with a height to stretch your ScrollView higher than your screen.

Wrapping ScrollView in a View with height > the screen will work too.

Borgeson answered 21/8, 2020 at 17:3 Comment(1)
If I wrap the ScrollView with another View <View style={{height: "auto", maxHeight: screenHeight*2}}>, the list rendered is just a plain view where the content is missing. I also tried adding height: "150%"to the searchResultsContainerbut it doesn't make a differenceAdminister
E
1

I think so you can fix this issue by following below tips: 1)Adjusting ScrollView tag position most probably it will go above your condition directly inside <></> or add view Tag,above ScrollView tag like

<><View style={{ Height: "auto", maxHeight: screenHeight}}><ScrollView>....</ScrollView></view></>

2)By adjusting height, maxHeight property and flex property

If it worked for you please let me know

Elka answered 22/8, 2020 at 7:10 Comment(2)
The condition is necessary. If I wrap the ScrollView with another View <View style={{height: "auto", maxHeight: screenHeight}}>, the list rendered is just a plain view where the content is missing.Administer
What exactly can I try to 'adjust height/max-height' and where? Adding it to the dropdowndidn't work.Administer
C
0

I can think of three solutions (you can try either one):

1-Try wrapping the scroll view inside a view tag with flex=1, like this:

<View style={{ flex:1 }}>
<ScrollView>
</ScrollView>
</View>

2-if you don't want to use a view you can set ScrollView flex to 1

3-in first solution you can use empty tag instead of View like so:

<> 
</>
Coriander answered 16/8, 2020 at 13:57 Comment(3)
Unfortunately, none of them worked form me. Also, there's one empty tag in my return already.Administer
Did you try using flatlist instead of scorllview?Coriander
Nope, not yet at least. I added some more info to the qs thoAdminister
B
0

If your problem is only with the keypad open then you might want to take a look at KeyboardAvoidingView

I have had a lot of problems with this! You want to try all of the settings for the prop behavior. there's probably one that works for you!

From their examples:

import React from 'react';
import { View, KeyboardAvoidingView, TextInput, StyleSheet, Text, Platform, 
TouchableWithoutFeedback, Button, Keyboard  } from 'react-native';

const KeyboardAvoidingComponent = () => {
   return (
     <KeyboardAvoidingView
       behavior={Platform.OS == "ios" ? "padding" : "height"}
       style={styles.container}
     >
       <TouchableWithoutFeedback onPress={Keyboard.dismiss}>
         <View style={styles.inner}>
           <Text style={styles.header}>Header</Text>
           <TextInput placeholder="Username" style={styles.textInput} />
           <View style={styles.btnContainer}>
             <Button title="Submit" onPress={() => null} />
           </View>
         </View>
       </TouchableWithoutFeedback>
     </KeyboardAvoidingView>
   );
 };

 const styles = StyleSheet.create({
   container: {
     flex: 1
   },
   inner: {
     padding: 24,
     flex: 1,
     justifyContent: "space-around"
   },
   header: {
     fontSize: 36,
     marginBottom: 48
   },
   textInput: {
     height: 40,
     borderColor: "#000000",
     borderBottomWidth: 1,
     marginBottom: 36
   },
   btnContainer: {
     backgroundColor: "white",
     marginTop: 12
   }
 });

 export default KeyboardAvoidingComponent;
Baldpate answered 19/8, 2020 at 17:43 Comment(0)
H
0

I made an expo snack for your problem and examined it. I think I solved it. take a look at it:

This is the link to the expo snack

To describe about it:

As I found out, your problem was that the ScrollView wasn't changing height in any situations, even by giving more height or giving paddingBottom.

so I wrapped the ScrollView in a View tag and gave this styling to it:

scrollViewWrapper: {
     width: '100%',
     minHeight: '100%',
     paddingBottom: 1.3*keyboardHeight
 }

In this styling, you see parameter keyboardHeight, which is a state that I'm setting in the componentDidMount with below codes:

import {Keyboard} from 'react-native';
 
state = {
  keyboardHeight: 0,
}

componentDidMount() {
this.keyboardDidShowListener = Keyboard.addListener(
  'keyboardDidShow',
  this._keyboardDidShow
);
this.keyboardDidHideListener = Keyboard.addListener(
  'keyboardDidHide',
  this._keyboardDidHide
 );
}
_keyboardDidShow = (e) => {
  this.setState({
    keyboardHeight: e.endCoordinates.height,
  });
};

I have to mention that you cannot move the style of paddingBottom: 1.3*keyboardHeight outside of the class component and place it in styles object, because the keyboardHeight is a state, it can be known just inside the component.

I suggest you to take a look at my code in expo snack to understand my descriptions better.

I hope this solve your problem.

Edit for functional components

use below code to detect keyboard height while writing functional components:

const [keyboardHeight, setKeyboardHeight] = useState(0)
const [scrollViewVisibility, setScrollViewVisibility] = useState(false)
useEffect(() => {
  Keyboard.addListener("keyboardDidShow", _keyboardDidShow);

  // cleanup function
  return () => {
    Keyboard.removeListener("keyboardDidShow", _keyboardDidShow);
  };
}, []);
const _keyboardDidShow = (e) => {
  console.log("============in keyboardDidShow")
  setKeyboardHeight(e.endCoordinates.height)
};

I edited the expo snack too. you can take a look at it to see a working example.

Hauser answered 20/8, 2020 at 13:46 Comment(8)
Could you modify it according to the functional components? For state we can use useState and for componentDidMount we can use useEffect but I am unable to figure out how to replace this.keyboardDidShowListener in my case.Administer
Also, I can't really evaluate your snack expo since its a bit different than mine. In my case, once the list is displayed, the keyboard is still open. However, in your expo, the keyboard disappears when I search for the list is displayed.Administer
@Jnl I modified the expo snack and wrote an edit for this solution. check it out. about the difference between my code and yours, yes, there are some differences but I think you have checked my snack on the web mode, check it on iPhone mode. You'll see that it's so similar to yours.Hauser
This kinda works if I add an additional height:'80%' to my dropdown Viewwhich is the parent of the whole LocationsFound list component. Is it possible to move the height styling within LocationsFound as well? Such that it can automatically be calculated on different screens.Administer
My LocationFound is like your expo, minus the container View & TextInput at the very top. If I don't add the height to dropdown separately, it doesn't scroll.Administer
@Jnl If your LocationsFound component is like my expo snack, so you can wrap your whole component in a <View></View> tag (inside the component), then give it the paddingBottom: 1.3*keyboardHeight like my expo snack. I think if you do this, there will be no need to add a keyboardHeight related height to the dropdown View. If you make an expo snack of your problem, I can help you more.Hauser
I have already given the keyboardHeight as you suggest but it still requires an additional height. Unfortunately, the searching feature is too complex but I will still try to make an expoAdminister
@Jnl we do not need the searching method and codes. You can remove all lines that make up your list in the ScrollView and make it as simple as possible, like mine. keep me posted when you're done.Hauser
S
-1

just change the styling of ScrollView, try giving the height and it will work and then you can give height according to standard android.

Swami answered 6/11, 2021 at 15:26 Comment(1)
Hi @jozem, you are answering an old question and seems that your answer is not adding much information with respect to the others. Please consider to expand your pointSluggard

© 2022 - 2024 — McMap. All rights reserved.