React Native text field inside webview got overlap at last textfield - android

in my react native app i have one webview and inside that i have 4 textfield on that so when i focus last text input at that time keyboard is overlapping last text field not scroll automatically below is m code
render() {
return (
<View style={styles.mainView} >
<WebView
ref={r => this.webview = r}
style={{width:globals.screenWidth, height:globals.screenHeight}}
bounces={false}
style={{ flex: 1 }}
startInLoadingState
scalesPageToFit
javaScriptEnabledAndroid={true}
javaScriptEnabled={true}
domStorageEnabled = {true}
onNavigationStateChange={this.handleNavigationStateChange}
onLoadStart={() => {
}}
onLoadEnd={() => {
}}
source={{uri: this.state.url}}
onError={(error) => this.onError()}
/>
</View>
);
}
So any idea how can i solve this your all suggestions are appreciable

try to use https://github.com/APSL/react-native-keyboard-aware-scroll-view instead of View component.

Related

react-native webview in Expo App shows 'about:blank' on Android before exiting the APP with BackHandler

Good day everyone,
I have a problem with an App that gives me some headaches for couple days.
The App consists of a WebView containing a PHP WebShop and a bar-code scanner. So far everything was working as expected.
For better Navigation on Android I wanted to use the HardwareBackButton to go back in the WebView History. This also works well but has a major flaw.
I want the back button to go back until it cant go back anymore and instead it should exit the App.
Now to the actual problem: the last Page url is 'about:blank' and results in a blank screen. From here the canGoBack state is false and the App exits as expected but if you open the App again its still in the 'about:blank' state.
My first workaround was to add this.WEBVIEW_REF.current.goForward(); before BackHandler.exitApp;. This helps to get the App back in a navigateable state after exiting but i would like to completely get rid of the blank screen.
I Hope the code below is enough to understand what i wanted to achive:
componentDidMount() {
BackHandler.addEventListener('hardwareBackPress', this.handleBackButton);
}
componentWillUnmount() {
BackHandler.removeEventListener('hardwareBackPress', this.handleBackButton);
}
handleBackButton = () => {
if (this.state.canGoBack) {
this.WEBVIEW_REF.current.goBack();
return true;
}else{
this.WEBVIEW_REF.current.goForward();
BackHandler.exitApp;
};
}
render() {
<View style={styles.container}>
<CustomStatusBar backgroundColor="#ee7203" barStyle="light-content" />
<View style={styles.main}>
<WebView
onLoad={() => this.hideSpinner()}
cacheEnabled={false}
source={{
uri: this.state.webshopURL,
}}
ref={this.WEBVIEW_REF}
onNavigationStateChange={(navState) => {
console.log(navState);
this.setState({
canGoBack: navState.canGoBack,
currentUrl: navState.url,
});
}}
allowsBackForwardNavigationGestures={true}
incognito={true}
onMessage={(event) => {
this.handleWebMassage(event.nativeEvent.data);
}}
/>
{this.state.scannerOpen === true && (
<View style={styles.barcodeScannerContainer}>
<BarCodeScanner
onBarCodeScanned={
this.state.scanned ? undefined : handleBarCodeScanned
}
style={[StyleSheet.absoluteFill, styles.barcodeScanner]}
>
<BarcodeMask edgeColor="#62B1F6" showAnimatedLine={false}/>
<TouchableOpacity
onPress={() => this.closeScanner()}
style={styles.cancel}
light
>
<Icon name="close" color="#58585a" />
</TouchableOpacity>
</BarCodeScanner>
</View>
)}
</View>
{this.state.showSplash === true && (
<View style={styles.splash}>
<Animated.Image
onLoad={this.onLoad}
{...this.props}
style={[
{
opacity: this.state.opacity,
transform: [
{
scale: this.state.opacity.interpolate({
inputRange: [0, 1],
outputRange: [0.85, 1],
}),
},
],
},
this.props.style,
]}
style={styles.logo}
source={logo}
resizeMode={"contain"}
/>
</View>
)}
</View>
I found a workaround for the Problem. The App has a SplashScreen on start and I simply set the state of canGoBack to false and am clearing the WebViews history when the SplashScreen closes.
this.sleep(5000).then(() => {
this.setState({
showSplash: false,
canGoBack: false,
});
this.WEBVIEW_REF.current.clearHistory();
});

TextInput auto scroll to bottom in multiline in react native

I have a TextInput component, and i want to make text visible when keyboard is on, by default, android will have this, but i don't know why the multiline TextInput just scroll down to the bottom of the text exact the same behavior of single line ( also the cursor at the lastest text)
Here is the code of it
<SafeAreaView style={{ margin: spacingWidth[3], flex: 1 }}>
<View row centerV style={HEADER}>. //just set margin
<TouchableOpacity onPress={() => nav.goBack()}>
<BackArrow name="arrowleft" size={onePercentWidth * 6} />
</TouchableOpacity>
<TouchableOpacity
onPress={() => {
editAndSaveFirebase();
nav.goBack();
dispatch(switchReloadOn());
dispatch(fetchNote(userInfo.email)).then(() =>
dispatch(switchReloadOff())
);
// saveAndNavBack();
}}
>
<Text style={SAVE_NOTE_BT}>Save</Text>
</TouchableOpacity>
</View>
<TextInput
onChangeText={(text) => setNoteHeader(text)}
value={noteHeader}
placeholder="Meaningful header"
style={HEADER_INPUT}
/>
<ScrollView
showsVerticalScrollIndicator={false}
style={{
flex: 1,
}}
contentContainerStyle={{
flexGrow: 1,
}}
> ====> the problem here
<TextInput
scrollEnabled={false}
textAlignVertical={Platform.OS === "android" ? "top" : ""}
onChangeText={(text) => setNoteEdit(text)}
placeholder="Type your secret here..."
value={noteEdit}
multiline
style={NOTE_INPUT}. // i just set the fontSize
/>
</ScrollView>
</SafeAreaView>
);
Here is the behavior i talked about
You should set scrollEnabled: false only for iOS. If you still don't reach the expected behaviour, you can pass ref to the scrollView and scrollToEnd on TextInput focus.
const scrollViewRef = useRef<ScrollView>(null)
const handleInputFocus = () => {
if (isAndroid) {
setTimeout(() => scrollViewRef.current?.scrollToEnd({ animated: true }), 200)
}
}
<ScrollView ref={scrollViewRef}>
<TextInput
{...otherInputProps}
onFocus={handleInputFocus}
scrollEnabled={isAndroid}
/>
</ScrollView>

React native: Scroll view refresh control pull to refresh not refreshing from top

I have added pull to refresh inside web view using scroll view. It is working but the condition is that pull to refresh should only work when we are at the top of the page inside web view. Here is my code
<ScrollView
contentContainerStyle={{flex: 1}}
refreshControl={
<RefreshControl
refreshing={refreshing}
onRefresh={onRefresh}
/>
}
>
<WebView scalesPageToFit
startInLoadingState
ref = {webViewRef}
originWhitelist={['*']}
style={{ flex: 1 }} source={{ uri: url }} onLoadStart={() => (setLoading(true))} onLoadEnd={() => (setLoading(false))}
javaScriptEnabled={true}
domStorageEnabled={true}
setSupportMultipleWindows={false}
/>
</ScrollView>
Added onScroll method for web view and got the yOffset and added condition based on that to reload the webpage/not
<WebView scalesPageToFit
startInLoadingState
ref = {webViewRef}
originWhitelist={['*']}
style={{ flex: 1 }} source={{ uri: url }} onLoadStart={() => (setLoading(true))} onLoadEnd={() => (setLoading(false))}
javaScriptEnabled={true}
domStorageEnabled={true}
setSupportMultipleWindows={false}
onScroll={handleScroll}
/>
and the method
const handleScroll = (event) => {
console.log(Number(event.nativeEvent.contentOffset.y))
const yOffset = Number(event.nativeEvent.contentOffset.y)
if (yOffset === 0){
console.log('top of the page')
handleRefresh(true)
}else{
handleRefresh(false)
}
}

React native onStartShouldSetResponder parameter not working for AutoCompeletInput plugin

I am using plugin for Autocomplete Input. I have placed this component in Scrollview. It's other behaviour is fine like displaying suggestion list in popup with our custom design.
Referred Plugin:- Plugin
But onStartShouldSetResponder{()=>true} not working.
Because of that I am unable to scroll my suggestion list.
Here is my implemented code =>
<ScrollView keyboardShouldPersistTaps='always' style={[commonstyles.mainContainer,styles.mainContainer,{marginBottom:20}]}>
<View style={{width:width-30,height:45}}>
<Autocomplete
autoCapitalize="none"
autoCorrect={false}
hideResults={false}
containerStyle={{flex: 1,left: 10,position: 'absolute',right: 10,top: 0,zIndex: 1}}
data={films.length === 1 && comp(query, films[0].name) ? [] : films}
defaultValue={query}
onChangeText={text => this.setState({ query: text })}
placeholder="Select Contact"
renderItem={({ id,name }) => (
<TouchableOpacity onStartShouldSetResponder={()=>{return true;}} activeOpacity={1} onPress={() => this.setState({ query: name })}>
<Text style={{fontSize:Global.DESCRIPTION_FONT_SIZE,color:Global.APP_BLACK_COLOR,borderBottomWidth:0.5,borderColor:Global.APP_BLACK_COLOR,padding:5}}>
{id} {name}
</Text>
</TouchableOpacity>
)}
/>
</View>
</Scrollview>
Please let me know if I am doing something wrong.
Also I am unable to understand implementation of onStartShouldSetResponder() function.
Suggest Autocomplete input example in react native which work like Android AutoCompleteTexview component.
Add scrollEnabled parameter to your Scrollview.
Try with below code
<ScrollView scrollEnabled={this.state.enableScrollViewScroll} keyboardShouldPersistTaps='always' style={[commonstyles.mainContainer,styles.mainContainer,{marginBottom:20}]}>
<View style={{width:width-30,height:45}}>
<Autocomplete
autoCapitalize="none"
autoCorrect={false}
hideResults={false}
onStartShouldSetResponderCapture={() => {
var self=this;
this.setState({ enableScrollViewScroll: false });
console.log("Here==>",self.state.enableScrollViewScroll);
}}
containerStyle={{flex: 1,left: 10,position: 'absolute',right: 10,top: 0,zIndex: 1}}
data={films.length === 1 && comp(query, films[0].name) ? [] : films}
defaultValue={query}
onChangeText={text => this.setState({ query: text })}
placeholder="Select Contact"
renderItem={({ id,name }) => (
<TouchableOpacity activeOpacity={1} onPress={() => this.setState({ query: name,enableScrollViewScroll:true })}>
<Text style= {{fontSize:Global.DESCRIPTION_FONT_SIZE,color:Global.APP_BLACK_COLOR,borderBottomWidth:0.5,borderColor:Global.APP_BLACK_COLOR,padding:5}}>
{id} {name}
</Text>
</TouchableOpacity>
)}
/>
</View>
</Scrollview>

React-Native Navigator not rendering

I am trying to create routing between scenes using Navigator on React-Native (Android), However Navigator won't render the scene, Here is a simple snippet I've created.
<View>
<Navigator
initialRoute={{ name: 'LoginView' }}
renderScene={(route, naigator) => {
<Text styles={{fontSize: 20, fontWeight: 'bold'}}>Hello, World!</Text>
}}
/>
</View>
This should render the text Hello, World!, but a plain white screen showed up on the emulator.
You can use the Navigator component like this:
<Navigator
style={{flex: 1}}
ref={thisRef => {this.navigator = thisRef}}
initialRoute={{ title: 'Awesome Scene', index: 0}}
renderScene={(route, navigator) => {
if(route.index == 0) {
return <View>
<Text>Hello, World!</Text>
</View>
}
if(route.index == 1) {
return <View>
<Text>Hi, There</Text>
</View>
}
if(route.index == 2) {
return <View>
<Text>Hi, There...again!</Text>
</View>
}
}} />
That way you can go to another page using
this.navigator.push({title: "Awesome Scene 2", index: 1})
or
this.navigator.push({title: "Awesome Scene 3", index: 2})
and it will render the correct scene.
Hope this helps!
Just figured out why this happens, Since renderScene takes in a function it must return a single object of react native UI. So the UI code must be wrapped inside View as seen in these examples below:
<Navigator
initialRoute={{ title: 'Awesome Scene'}}
renderScene={(route, navigator) => {
<View>
<Text>Hello, World!</Text>
<Text>Hi, There</Text>
</View>
}}
/>

Categories

Resources