5

I have tried using both KeyboardAvoidingView and ScrollView to prevent my content from being squished (pushed up) when the keyboard is present. I have tried using padding, height, and position for my behavior but nothing is working. Can someone please tell me how I can force my content to ignore the keyboard and not get pushed up??

return (
    <View style={{height: '100%', backgroundColor: '#D6D6D6', position: 'relative'}}>
        <View style={styles.wrapper}>
            <View style={{height:'100%', borderRadius: 7}}>
                <View style={styles.container}>
                    <ScrollView style={{borderRadius: 7}}
                        horizontal
                        showsHorizontalScrollIndicator={false}
                        scrollEventThrottle={10}
                        pagingEnabled
                        onScroll={
                            Animated.event(
                                [{nativeEvent: {contentOffset: {x: this.animVal}}}]
                            )
                        }
                    >
                        {imageArray}
                    </ScrollView>
                    <View style={styles.listViewContainer}>
                        <TouchableOpacity style={styles.listView} onPress={() => Actions.pop()}>
                            <View style={{flex: 1, flexBasis: 22}}>{listIcon}</View>
                            <View style={{flex: 2, flexBasis: 57}}><Text style={{color: '#fff'}}>List View</Text></View>
                        </TouchableOpacity>
                    </View>
                    <View style={styles.circleContainer}>
                        {circleArray}
                    </View>
                </View>
                <View style={styles.productsSection}>
                    <Text style={styles.title}>{prodDesc}</Text>
                    <Text style={styles.desc}>{prodBrand}</Text>
                    <Text style={styles.desc}>Item: {prodId || ''}</Text>
                    <Text style={[styles.desc, {marginBottom: 15}]}>Category: {prodCat}</Text>
                    <Table borderStyle={{borderWidth: 0}}>
                        <Rows data={rows}/>
                    </Table>
                </View>
                <View style={styles.bodyFooter}>
                    <QuantityCounter style={{width: '100%', display: 'block', marginRight: 20}} data={{productId: prodId}} />
                </View>
            </View>
        </View>
        <View style={styles.footer}>
            <View style={styles.cartContainer}>
                {cartIcon}
                <Text style={{color: '#3A3A3A', fontSize: 14}}>18 items</Text>
            </View>
            <TouchableOpacity style={styles.viewCartButtonContainer} onPress={() => this.cartRedirect() }>
                <Text style={{color: '#fff', fontSize: 15, marginTop: '5%'}}>View Cart</Text>
            </TouchableOpacity>
        </View>
        <Header/>
    </View >
);

here are my main styles for this:

var styles = StyleSheet.create({
    wrapper: {
        backgroundColor: '#E6E6E6',
        marginVertical: 15,
        marginHorizontal: 10,
        borderRadius: 7,
        elevation: 3,
        maxHeight: '80%',
        flexShrink: 1,
        zIndex: 0,
        marginTop: 75
    },
    container: {
        flex: 1.7,
        justifyContent: 'space-between',
        alignItems: 'center',
        height: '50%',
        borderRadius: 7
    },
    footer: {
        justifyContent:'space-between',
        alignItems: 'center',
        height: '10%',
        backgroundColor: '#E6E6E6',
        paddingVertical: 15,
        paddingHorizontal: 17,
        flexDirection: 'row',
        borderStyle: 'solid',
        borderTopColor: '#8E8E93',
        borderTopWidth: 1
    },
    cartContainer: {
        flexDirection: 'row',
        width: '35%'
    },
    viewCartButtonContainer: {
        backgroundColor: '#356FAF',
        height: '90%',
        width: '45%',
        padding: 20,
        alignItems: 'center',
        justifyContent: 'center',
        borderRadius: 3
    },
    bodyFooter: {
        backgroundColor: '#F6F6F6',
        justifyContent: 'center',
        flex: 0.45,
        borderTopColor: '#D6D6D6',
        borderTopWidth: 1,
        borderStyle: 'solid',
        borderBottomRightRadius: 7,
        borderBottomLeftRadius: 7
    },
    circleContainer: {
        position: 'absolute',
        zIndex: 2,
        bottom: 10,
        left: 10,
        flexDirection: 'row',
    },
    listViewContainer: {
        position: 'absolute',
        zIndex: 10,
        top: 0,
        right: 0,
        justifyContent: 'center'
    },
    listView: {
        display: 'flex',
        flexDirection: 'row',
        alignItems: 'center',
        justifyContent: 'center',
        borderTopRightRadius: 3,
        backgroundColor: '#000',
        paddingVertical: 5,
        paddingHorizontal: 10
    },

What it looks like without the keyboard:

enter image description here

What it looks like with the keyboard:

enter image description here

FairyQueen
  • 2,283
  • 7
  • 37
  • 57

6 Answers6

10

Handling View behavior when toggling a keyboard can be a tricky thing in React Native. There are multiple possible solutions to questions like this, but in this case the solution was this:

Instead of using style={{height:'100%'}} on your components that get pushed up, try using Dimensions:

import {Dimensions} from 'react-native'; 
const { height } = Dimensions.get('window');

and specify style={{ height }} in the right components.


Another thing that might be worth a try if someone else stumbles on this question:

React Native for Android has some default settings defined in the Android manifest. If you are not using Expo (or CRNA), you can change the behavior of the keyboard in AndroidManifest.xml by changing the windowSoftInputMode rule.

Try changing android:windowSoftInputMode="adjustResize" to android:windowSoftInputMode="adjustPan" or to android:windowSoftInputMode="adjustNothing". You can try to play around with some other options (See here) if this doesn't give you the desired effect.

brkn
  • 646
  • 5
  • 11
  • I switched my android:windowSoftInputMode from adjustResize to adjustPan but it still did not work. Do I need to do a rebuild since its in the Android manifest file?? – FairyQueen May 03 '18 at 14:08
  • Yes, you need to rebuild if you change native code (code inside the android or ios folder) – brkn May 03 '18 at 14:35
  • I have since rebuilt but nothing has changed. I still get my content pushed up when the keyboard is present :( – FairyQueen May 03 '18 at 14:39
  • Even with `adjustPan` and without a KeyboardAvoidingView? Can you try changing it to `adjustNothing`? – brkn May 03 '18 at 14:42
  • Yes when I try it as you have suggested I have not included KeyboardAvoidingView. I tried adjustNothing and rebuilt but I still get the content pushed up. – FairyQueen May 03 '18 at 15:13
  • This line is right above it in my Android manifest file: android:configChanges="keyboard|keyboardHidden|orientation|screenSize" Should that be changed at all?? – FairyQueen May 03 '18 at 15:14
  • When I "rebuild" I close the android emulator, wipe the data, click 'Rebuild Project' under the Build menu and then click the "Play" triangle button. Is there something else I need to do to make sure the Android manifest is actually updating? – FairyQueen May 03 '18 at 15:20
  • No there is nothing else you need to do, that should be enough to ensure your native changes are built when you run the app. It might be impossible to achieve what you want, without writing some native code (see this thread for examples of how to fix in native Android https://stackoverflow.com/q/4207880/5791025). – brkn May 03 '18 at 15:29
  • 1
    Can you try doing this: instead of using style={{height:'100%'}} on your components that get pushed up, try using Dimensions. `import {Dimensions} from 'react-native'; const { width, height } = Dimensions.get('window'); and specify style={{height}}. This is my last idea however, if this doesn't work I'm not sure how to tackle this problem. – brkn May 03 '18 at 15:34
  • OMG that actually worked!!! Haha can't believe the last try finally got it. I did this for the assigning 'style={{height: height' on my outer most View. If you want to make your comment into an answer I'll accept it. – FairyQueen May 03 '18 at 16:29
  • Glad it worked! I edited my answer to include the solution. – brkn May 04 '18 at 07:31
2

You should use try behavior as "none" for android and if you don't want to getting small, you can set android:windowSoftInputMode="adjustPan" in manifest file.

and if still face any error checkout react-native-keyboard-aware-scrollview here on npm.

  • I switched my android:windowSoftInputMode from adjustResize to adjustPan and switched back to using KeyboardAvoidingView and made the behavior be "none" but it still did not work. I still get my content being squish (pushed up) but I also get a warning now that "none" is not a valid value (only padding, height, and position are). – FairyQueen May 03 '18 at 14:04
  • oh my fault it should be null try something like behavior={Platform.OS == "ios " ? 'height' : null} for both. and yes. when you change manifest make sure to re install. not sure you did or not so mantioned. – Prashant Dhameja May 03 '18 at 14:15
  • What do you mean by "both"? How do I do behavior={Platform.OS == "ios " ? 'height' : null} for both? What is the both? I thought "behavior" was just a prop on KeyboardAvoidingView??? – FairyQueen May 03 '18 at 14:21
  • i meant both that usually people use React-native for both platforms. and they preffered in documentation that Note: Android and iOS both interact with this prop differently. Android may behave better when given no behavior prop at all, whereas iOS is the opposite. so via this condition it will take height or whatever you want on ios and null on android. – Prashant Dhameja May 03 '18 at 14:26
  • I tried behavior={Platform.OS == "ios " ? 'height' : null} but I don't have the variable Platform so I couldn't use that. I tried height and null each separately though. behavior="height" and then behavior="null" but neither is working. They both still have the content pushed up and "null" gives me a warning saying its not a valid value. – FairyQueen May 03 '18 at 14:37
  • i meant null not "null". if its only on android, just remove the prop anyways. – Prashant Dhameja May 03 '18 at 17:20
0

I went through a similar problem and solved it by changing android:windowSoftInputMode="adjustPan”

In android manifest. Also clean and rebuild. This might work

sharad_kalya
  • 255
  • 1
  • 3
  • 11
0

remove the position absolute it will works just fine trust me

Rahul Shakya
  • 1,269
  • 15
  • 15
0

for some cases if you want keep defualt manifest you can move your elements inside a Scrollview it may help.

issue solved for me in this way

faryar76
  • 130
  • 1
  • 8
0

use zIndex for the element that you want to be displayed

sofian
  • 1
  • 1