Issue
I am using react-native-webview(https://github.com/react-native-webview/react-native-webview/blob/master/docs/Reference.md) to show some html inside both android and ios devices.
Webview is showing all htmls correctly on iOS but on android there are some htmls which aren't displaying consistently. Below is one example which doesn't display on android but does display on iOS.
<!Doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>;</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<h2 dir="auto"><strong style="color: rgb(230, 0, 0); background-color: transparent;" dir="auto">What to See and What to Do In London </strong></h2>
<p dir="auto" style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><span style="font-size:11pt;font-family:Arial;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;" dir="auto">We visited England on such countless events and we love its capital city given the sheer number of marvelous activities in London. During our heartfelt 4 days in London schedule, we invested such a lot of energy simply absorbing what the city brings to the table. London implies a great deal to us too, as this is the city where we requested our wedding bands from. It's likewise the very first city we had a movement date in, with a cool visit around Tate Modern. We are sure you will go gaga for London and will need to return for additional. Also, assuming you visit London with your family, have confidence there are a lot of free London exhibition halls for youngsters too.</span></p>
</body>
</html>
My code:
const {html} = props
const newHtml = `<h2 dir="auto"><strong style="color: rgb(230, 0, 0); background-color: transparent;" dir="auto">What to See and What to Do In London </strong></h2><p dir='auto' style='line-height:1.38;margin-top:0pt;margin-bottom:0pt;'><span style='font-size:11pt;font-family:Arial;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;' dir='auto'>We visited England on such countless events and we love its capital city given the sheer number of marvelous activities in London. During our heartfelt 4 days in London schedule, we invested such a lot of energy simply absorbing what the city brings to the table. London implies a great deal to us too, as this is the city where we requested our wedding bands from. It's likewise the very first city we had a movement date in, with a cool visit around Tate Modern. We are sure you will go gaga for London and will need to return for additional. Also, assuming you visit London with your family, have confidence there are a lot of free London exhibition halls for youngsters too.</span></p>`
const htmlStr = '<\!Doctype html><html><head><meta charset="UTF-8"><title>;</title><meta name="viewport" content="width=device-width, initial-scale=1.0"></head><body>' + html.toString() + '</body></html>'
const webiewStyle = {...styles.webView, minHeight: (html.length)}
console.log('htmlStr', htmlStr)
const [webViewHeight, setWebViewHeight] = useState((html.length))
const webViewStyle = useMemo(() => ({height: webViewHeight}), [webViewHeight])
return (
<View style={styles.container}>
<WebView
style={[webiewStyle, webViewStyle]}
source={{html: htmlStr, baseUrl: ''}}
javaScriptEnabled={true}
domStorageEnabled={true}
scalesPageToFit={true}
scrollEnabled={false}
automaticallyAdjustContentInsets={false}
androidHardwareAccelerationDisabled={true}
androidLayerType={Platform.OS === 'ios' ? 'hardware' : ''}
startInLoadingState={true}
originWhitelist={['*']}
onMessage={event => { setWebViewHeight(parseInt(event.nativeEvent.data)+10)}}
injectedJavaScript='window.ReactNativeWebView.postMessage(document.body.scrollHeight)'
// useWebKit={true}
viewportContent={'width=device-width, user-scalable=no, initial-scale=1.0'}
onContentProcessDidTerminate={(syntheticEvent) => {
const { nativeEvent } = syntheticEvent
console.log('Content process terminated, reloading', nativeEvent)
this.refs.webview.reload()
}}
onError={(syntheticEvent) => {
const { nativeEvent } = syntheticEvent
console.log('WebView error: ', nativeEvent)
}}
mixedContentMode={'always'}
onRenderProcessGone={() => alert('ahooo')}
overScrollMode={'never'}
/>
</View>
)
Below is HTML which works fine for both android and ios devices.
<!Doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>;</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<p dir="auto" style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant-numeric: normal; font-variant-east-asian: normal;" dir="auto">Thinking about what are the best activities in London? Home to 4 world legacy locales, established by the Romans and the present one of the main monetary center points on the planet, London is an assorted city, known for its craft, culture, religions, and trendy personal areas. London is one of the world's greenest urban communities, home to the notorious Big Ben and the Royal Family. London is a dynamic city, brimming with promising circumstances and probably the coolest spot in Europe. Britain's capital is a flat-out must-see.</span></p>
</body>
</html>
Solution
I was able to find the solution. So I used below props for WebView on android. I had to use androidLayerType={'hardware'} but it introduced crashing issue for android navigation. So I used androidLayerType={'hardware'} and opacity: 0.99 in styles. For more detail check below code.
const styles = StyleSheet.create({
container: {justifyContent: 'center', marginBottom: 10, opacity: 0.99, overflow: 'hidden' , width: '100%'},
webView: { height: 'auto', marginBottom: 20, marginTop: 20, opacity: 0.99, overflow: 'hidden', width: Metrics.screenWidth - 50 }
})
const HTMLView = props => {
const {html} = props
// const newHtml = `<h2 dir="auto"><strong style="color: rgb(230, 0, 0); background-color: transparent;" dir="auto">What to See and What to Do In London </strong></h2><p dir='auto' style='line-height:1.38;margin-top:0pt;margin-bottom:0pt;'><span style='font-size:11pt;font-family:Arial;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;' dir='auto'>We visited England on such countless events and we love its capital city given the sheer number of marvelous activities in London. During our heartfelt 4 days in London schedule, we invested such a lot of energy simply absorbing what the city brings to the table. London implies a great deal to us too, as this is the city where we requested our wedding bands from. It's likewise the very first city we had a movement date in, with a cool visit around Tate Modern. We are sure you will go gaga for London and will need to return for additional. Also, assuming you visit London with your family, have confidence there are a lot of free London exhibition halls for youngsters too.</span></p>`
const htmlStr = '<\!Doctype html><html><head><meta charset="UTF-8"><title> </title><meta name="viewport" content="width=device-width, initial-scale=1.0"></head><body>' + html.toString() + '</body></html>'
const webiewStyle = {...styles.webView, minHeight: (html.length)}
const [webViewHeight, setWebViewHeight] = useState((html.length))
const webViewStyle = useMemo(() => ({height: webViewHeight}), [webViewHeight])
// const webViewStyle = {height: webViewHeight}
return (
<View
style={styles.container}
>
{Platform.OS === 'ios' ? <WebView
style={[webiewStyle, webViewStyle]}
source={{html: htmlStr, baseUrl: ''}}
javaScriptEnabled={true}
domStorageEnabled={true}
scalesPageToFit={true}
scrollEnabled={false}
automaticallyAdjustContentInsets={false}
startInLoadingState={true}
originWhitelist={['*']}
onMessage={event => { setWebViewHeight(parseInt(event.nativeEvent.data)+10)}}
injectedJavaScript='window.ReactNativeWebView.postMessage(document.body.scrollHeight)'
// useWebKit={true}
viewportContent={'width=device-width, user-scalable=no, initial-scale=1.0'}
onContentProcessDidTerminate={(syntheticEvent) => {
const { nativeEvent } = syntheticEvent
console.log('Content process terminated, reloading', nativeEvent)
this.refs.webview.reload()
}}
onError={(syntheticEvent) => {
const { nativeEvent } = syntheticEvent
console.log('WebView error: ', nativeEvent)
}}
/> : <WebView
style={[webiewStyle, webViewStyle]}
source={{html: htmlStr, baseUrl: ''}}
javaScriptEnabled={true}
domStorageEnabled={true}
scalesPageToFit={true}
nestedScrollEnabled={false}
automaticallyAdjustContentInsets={false}
androidHardwareAccelerationDisabled={false}
androidLayerType={'hardware'}
startInLoadingState={true}
originWhitelist={['*']}
onMessage={event => { setWebViewHeight(parseInt(event.nativeEvent.data)+10)}}
injectedJavaScript='window.ReactNativeWebView.postMessage(document.body.scrollHeight)'
useWebKit={true}
viewportContent={'width=device-width, user-scalable=no, initial-scale=1.0'}
onContentProcessDidTerminate={(syntheticEvent) => {
const { nativeEvent } = syntheticEvent
console.log('Content process terminated, reloading', nativeEvent)
this.refs.webview.reload()
}}
onError={(syntheticEvent) => {
const { nativeEvent } = syntheticEvent
console.log('WebView error: ', nativeEvent)
}}
mixedContentMode={'always'}
overScrollMode={'never'}
/>}
</View>
)
}
I am using both androidLayerType={'hardware'} and androidHardwareAccelerationDisabled={false} here. (Although some solutions suggested otherwise.)
I was also facing the crash issue due to'react-native-youtube-iframe' and to fix this I used opacity: 0.99 for webViewStyle prop in this component.
I also applied opacity:0.99 for all webviews I was showing inside the list of item.
Answered By - Adnan Ali
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.