WebView scroll is not working in Android. I have searched a lot and seen a lot of other places, no one was able to help.
This is how I defined the component
<WebView
automaticallyAdjustContentInsets={false}
source={{uri: this.props.url}}
javaScriptEnabled={true}
domStorageEnabled={true}
decelerationRate="normal"
startInLoadingState={true}
scalesPageToFit={isAndroid ? false : true}
/>
This seems a react native bug (which is out there forever), but there should be a workaround.
-- UPDATE --
I figured out that this is not the WebView problem and it's happening because I have it in a Modal and TouchableWithoutFeedback is needed to hide the modal and of course not hide when they touch inside the modal.
TouchableWithoutFeedback steals the press event and does not the scroll work.
<Modal
animationType='fade'
onRequestClose={() => { }}
transparent
visible={visible} //its either true or false, if its ture it will be displayed if false, it will hide
>
<TouchableWithoutFeedback onPress={onDecline} >
<View style={containerStyle}>
<Ionicons name="md-close" size={24} color={colors.primary} style={closeIconStyle} />
<TouchableWithoutFeedback onPress={() => { }} >
<View style={popupStyle}>
<View style={styles.textContainer}>
<Text style={textStyle}>
{this.props.title}
</Text>
</View>
<View style={[cardSectionStyle, {
marginTop: 5
}]}>
<View style={{ height: SCREEN_HEIGHT - 300, width: SCREEN_WIDTH - 80 }}>
<WebView
source={{ uri: this.props.url }}
style={contentStyle}
automaticallyAdjustContentInsets={false}
javaScriptEnabled={true}
domStorageEnabled={true}
decelerationRate="normal"
startInLoadingState={true}
/>
</View>
</View>
</View>
</TouchableWithoutFeedback>
</View>
</TouchableWithoutFeedback>
</Modal>
Adding "nestedScrollEnabled" property in WebView worked for me
You can add style={flex: 1} in the <Webview /> tag.
If it's still not working, just try this:
<WebView
source={{uri: this.props.url }}
style={{marginTop: 20, flex: 1}}
javaScriptEnabled={true}
domStorageEnabled={true}
startInLoadingState={true}
/>
Related
How to set full screen image inside Modal that supports all device screen sizes without starching image in react-native ?
<Modal
animationType="fade"
visible={props.isOpen}
onRequestClose={props.onCloseModal}>
<SafeAreaView style={{ flex: 1, backgroundColor: 'white' }}>
<View style={{flex: 1}>
<Image source={"path/to/local/image"} resizeMode='stretch' style={imageStyle}/>
</View>
</SafeAreaView>
</Modal>
Use cover for resizeMode in Image.
<Modal
...
>
<Image
resizeMode="cover"
style={{width: '100%', height: '100%'}}
source={{
uri: 'https://reactnative.dev/img/tiny_logo.png',
}}
/>
</Modal>
I'm using AppIntroSlider with LottieAnimations and i have troubles with animation launching on IOS.
<View style={styles.slide}>
<View style={styles.titleContainer}>
<Text style={styles.title}>{item.title}</Text>
</View>
{item.key > 1 && (
<LottieView
source={item.lottieAnimation}
autoPlay={true}
loop={true}
speed={0.7}
/>
)}
<Image source={item.image} style={styles.image} />
<Text style={styles.text}>{item.text}</Text>
</View>
It shows only a frist frame and animation doesn't start.
"lottie-react-native": "^5.0.1"
I'm trying to create vertical flatlist with swipe to delete functionality. So every item of my flatlist additionaly handles by PanGestureHandler My problem is when I try to scroll my flatlist scroll doesn't work because of the conflict between scroll view animation and the pan gesture animation. I have tried to use simultaneousHandlers but it doesn't help.
I also tried to use FlatList from react-native-gesture-handler and from react-native result is the same.
<View style={styles.container}>
<Header data={{headerText: 'Contacts', leftIcon: 'arrow-left', line: true}}/>
<FlatList
ref={scrollRef}
data={contacts}
renderItem={({item}) => <Item simultaneousHandlers={scrollRef} {...{item}} />}
bounces={false}
showsVerticalScrollIndicator={false}
style={{paddingLeft: wp('5%'), paddingTop: hp('2%')}}>
</FlatList>
<TouchableOpacity style={styles.touchableOpacity} onPress={() => navigation.navigate('AddContact')}>
<View>
<Text style={styles.textButton}> Add Contact </Text>
</View>
</TouchableOpacity>
</View>
Item:
<Animated.View style={[rTaskContainerStyle]}>
<Animated.View style={[styles.iconContainer, rIconContainerStyle]}>
<Icon name={'trash-2'} size={25} color={'red'} />
</Animated.View>
<View>
<PanGestureHandler {...simultaneousHandlers} onGestureEvent={panGestureHandler}>
<Animated.View style={[rStyle,{backgroundColor: '#FFFFFF'}]}>
<Text style={{color: '#09101D', fontFamily: 'SourceSansPro_600SemiBold', fontSize: 18}}>
{info.fullName}
</Text>
<Text style={{color: '#545D69', fontFamily: 'SourceSansPro_400Regular'}}>
{info.publicKey}
</Text>
</Animated.View>
</PanGestureHandler>
</View>
</Animated.View>
You should add offset for pan-gesture. Your PanGestureHanler should be
<PanGestureHandler
failOffsetY={[-5, 5]}
activeOffsetX={[-5, 5]}
onGestureEvent={gestureHandler}
>
It may help you.
render() {
return (
<View style ={styles.container}>
{/*for header*/}
<View style = {{flexDirection:'row',justifyContent:'space-between',alignItems: 'center',width:'100%',height:'09%',backgroundColor: '#009AFF'}}>
<TouchableWithoutFeedback onPress={() =>this.props.navigation.goBack()}>
<Image style={{width: 25, height: 25,margin:10}} source={require('../assets/clinic/left-arrow.png')} />
</TouchableWithoutFeedback>
<View>
<Text style={{fontSize: 21,fontWeight: 'bold', color: "white",paddingRight:25}}>Dummy</Text>
</View>
<View>
</View>
</View>
{/*for main content*/}
<ScrollView style={{width:'100%',height:'90%'}} contentContainerStyle={{ flexGrow: 1 }} nestedScrollEnabled={true}>
<View>
<View style = {{width:'100%',height:'45%',backgroundColor: '#009AFF',justifyContent:'center',alignItems: 'center'}}>
<Text style={{fontSize: 18,fontWeight: 'bold', color: "white",paddingRight:25}}>John Alison</Text>
</View>
<TouchableOpacity
style={styles.submitButton}>
<Text style={styles.submitText}>Update</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.submitButton}>
<Text style={styles.submitText}>Update</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.submitButton}>
<Text style={styles.submitText}>Update</Text>
</TouchableOpacity>
</View>
</ScrollView>
</View>
)
}
Above code i have implemented in react native for learning purposes.But in above code ScrollView does not works,means it does not scrolls,why? i have tried many possible ways like setting flex and flexGrow equal to 1,enabling nested scrolling but it does not works.What is wrong with my code
I'm building a 'Search' component, in which a ScrollView is displayed when the search terms in the TextInput return related tags from the API endpoint. While running in iOS the component works as expected and allows me to scroll through the list and select an option. However, android does not seem to allow scroll or touch events on the ScrollView component. I've decorated the component with the keyboardShouldPersistTaps="always" and nestedScrollEnabled={true}.
Attempted placing the ScrollView at different levels of the overall screen. When close to the top level View, the ScrollView works as intended, but at a certain depth, it ceases to work. Having the ScrollView higher up in the component would require a lot of calculation based on the onLayout events of each nested View in order for the component to match designs, so I'd like to avoid it if possible.
<ScrollView
style={Style.view}
contentContainerStyle={Style.container}
keyboardShouldPersistTaps="handled"
>
<TouchableOpacity
onPress={this.onClose}
style={Style.close}
hitSlop={{
top: 16,
right: 16,
bottom: 16,
left: 16,
}}
>
<Icon
name="times"
size={24}
color={Palette.$color_white}
/>
</TouchableOpacity>
<Animated.View style={[Style.animatedWrapper, { transform: [{ translateY }] }]}>
<View style={Style.tags}>
{
tags.map(tag => (
<View key={tag.guid} style={Style.tag}>
<Strong color={Palette.$color_white}>{tag.name}</Strong>
<TouchableOpacity
style={Style.tagButton}
onPress={() => this.onTagPress(tag)}
hitSlop={{
top: 16,
right: 16,
bottom: 16,
left: 16,
}}
>
<Icon name="times" size={14} color={Palette.$color_white} />
</TouchableOpacity>
</View>
))
}
</View>
<View style={Style.searchWrapper} onLayout={this.onLayout}>
<Image
source={Buzz}
style={Style.illustration}
/>
<View style={Style.inputWrapper}>
<Heading
level={3}
color={Palette.$color_white}
>
Search by key words
</Heading>
<View style={Style.controlWrapper}>
<View style={{ flex: 1 }}>
<TextInput
ref={(ref) => { this.input = ref; }}
returnKeyType="done"
textContentTypez="none"
placeholder="Type your search"
onChangeText={this.onChangeText}
onFocus={this.onFocus}
onBlur={this.onBlur}
underlineColorAndroid="transparent"
placeholderTextColor={Palette.$color_white}
style={Style.searchInput}
/>
<Animated.View
style={[Style.menu, { opacity: menuOpacity }]}
pointerEvents={isMenuOpen ? 'auto' : 'none'}
>
<ScrollView
contentContainerStyle={Style.menuOptionsContentContainer}
keyboardShouldPersistTaps="always"
style={[Style.menuOptions, { maxHeight: scrollHeight }]}
nestedScrollEnabled
>
{
!isLoading
? results.map(tag => (
<TouchableHighlight
style={Style.menuOption}
key={tag.guid}
onPress={() => this.onOptionSelect(tag)}
underlayColor={Palette.$color_light_grey}
>
<Text style={Style.menuOptionText}>{tag.name}</Text>
</TouchableHighlight>
))
: (
<View style={Style.activityIndicator}>
<ActivityIndicator size="small" color={Palette.$color_orange} />
</View>
)
}
</ScrollView>
</Animated.View>
</View>
<StyledTextButton
title="Search"
onPress={this.onSearchPress}
disabled={tags.length <= 0}
/>
</View>
</View>
</View>
</Animated.View>
</ScrollView>
The ScrollView is rendered as expected, but in android it cannot respond to touch and swipe gestures. Works as intended in iOS.
Here's an example in iOS of the Component.