Live view loading indicator
I am trying to show a loading indicator in a webweb as shown below. A loading indicator is shown, but after the page has loaded, a white background is displayed. If I change startInLoadingState to false, the web content is shown, but the loading indicator is not shown. It jumps into "react-native": "0.46.3" on ios
renderLoadingView() {
return (
<ActivityIndicator
animating = {this.state.visible}
color = '#bc2b78'
size = "large"
style = {styles.activityIndicator}
hidesWhenStopped={true}
/>
);
}
<WebView
source={source}
renderLoading={this.renderLoadingView} startInLoadingState={true} />
source to share
I like this approach, which shows an activity indicator overlaid on the loading webview, so you don't have to wait for the entire page to load to start browsing the content.
constructor(props) {
super(props);
this.state = { visible: true };
}
hideSpinner() {
this.setState({ visible: false });
}
render() {
return (
<View style={{ flex: 1 }}>
<WebView
onLoad={() => this.hideSpinner()}
style={{ flex: 1 }}
source={{ uri: this.props.navigation.state.params.url }}
/>
{this.state.visible && (
<ActivityIndicator
style={{ position: "absolute", top: height / 2, left: width / 2 }}
size="large"
/>
)}
</View>
);
}
source to share
A good approach is to set the startInLoadingState property to true and set renderLoading to return the desired view. See the example below.
displaySpinner() {
return (
<View>
{/* Your spinner code goes here.
This one commes from react-native-material-kit library */}
<SingleColorSpinner />
</View>
);
}
render() {
return (
<WebView
startInLoadingState={true}
source={{ uri: this.state.myUri }}
renderLoading={() => {
return this.displaySpinner();
}}
/>
);
}
source to share
I solved this problem and after some research I found a pretty good solution.
This requires "overlay react-load-rotate-overlay"
npm install --save react-native-loading-spinner-overlay
index.android.js
import Spinner from 'react-native-loading-spinner-overlay';
const main = 'http://www.myURI.pt';
class MyApp extends Component {
constructor(props) {
super(props);
this.state = { uri: main, visible: true };
}
showSpinner() {
console.log('Show Spinner');
this.setState({ visible: true });
}
hideSpinner() {
console.log('Hide Spinner');
this.setState({ visible: false });
}
render() {
return (
<View>
<Spinner
visible={this.state.visible}
textContent={'Loading...'}
textStyle={{ color: '#FFF' }}
/>
<WebView
scalesPageToFit
source={{ uri: this.state.uri }}
onLoadStart={() => (this.showSpinner())}
onLoad={() => (this.hideSpinner())}
/>
</View>
);
}
}
I think I haven't missed a single line.
source to share
Modify the function renderLoadingView
as follows and the loading indicator should work as desired:
renderLoadingView() {
return (
<ActivityIndicator
color='#bc2b78'
size='large'
styles={styles.activityIndicator}
/>
);
}
Essentially, just remove animating
(as is not required for this use) and hidesWhenStopped
props from your ActivityIndicator
. Hope this helps.
source to share
I used @ solution AdamG's
but there is a problem with absolute path. The solution below sets ActivityIndicator
in the center, but in a different way.
<View style={{ flex: 1 }}>
<WebView
onLoad={() => this.hideSpinner()}
style={{ flex: 1 }}
source={{ uri: 'yourhtml.html' }}
/>
<View style={{backgroundColor:'white', height:1}}></View>
{this.state.visible && (
<View style={{flex:1, alignItems:'center'}}>
<ActivityIndicator
size="large"
/>
</View>
)}
</View>
There are 2 more View
{flex: 1} as well ActivityIndicator
located at the top of the bottom view. I focused it.
<View style={{backgroundColor:'white', height:1}}></View>
And this line sets the opacity, when you have the loading state, there are two different views there. The top view is WebView
and is a black bottom border of the View that belongs to. WebView
For the closure, I fixed it with a white auxiliary view.
source to share
Hey bro this is my solution, you have to use onLoadEnd event instead of onLoad, onLoad event doesn't work for me.
import React, { Component } from 'react';
import { StyleSheet, ActivityIndicator, View } from 'react-native';
import { WebView } from "react-native-webview";
export default class MainActivity extends Component {
constructor(props) {
super(props);
this.state = { visible: true };
}
showSpinner() {
console.log('Show Spinner');
this.setState({ visible: true });
}
hideSpinner() {
console.log('Hide Spinner');
this.setState({ visible: false });
}
render() {
return (
<View
style={this.state.visible === true ? styles.stylOld : styles.styleNew}>
{this.state.visible ? (
<ActivityIndicator
color="#009688"
size="large"
style={styles.ActivityIndicatorStyle}
/>
) : null}
<WebView
style={styles.WebViewStyle}
//Loading URL
source={{ uri: 'https://aboutreact.com' }}
//Enable Javascript support
javaScriptEnabled={true}
//For the Cache
domStorageEnabled={true}
//View to show while loading the webpage
//Want to show the view or not
//startInLoadingState={true}
onLoadStart={() => this.showSpinner()}
onLoad={() => this.hideSpinner()}
/>
</View>
);
}
}
const styles = StyleSheet.create({
stylOld: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
styleNew: {
flex: 1,
},
WebViewStyle: {
justifyContent: 'center',
alignItems: 'center',
flex: 1,
marginTop: 40,
},
ActivityIndicatorStyle: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
position: 'absolute',
},
});
source to share