使用框架 react-native-webview
安裝 react-native-webview
yarn add react-native-webview
在放在根目錄下,創(chuàng)建一個(gè).bundle文件羊初,將html酸役、靜態(tài)資源癣漆、css放到bundle里面如圖
1.引入
import WebView from 'react-native-webview'
2.創(chuàng)建web 增加屬性 originWhitelist={['*']}//解決iOS無法打開bundle里面的html問題 中文亂碼顯示的問題
onMessage
接受來自HTML的消息
使用this.webview.postMessage(JSON.stringify(data))
給HTML發(fā)送消息
render() {
let source = (Platform.OS === 'android' ? 'file:///android_asset/' : '') + `Static.bundle/index.html`;
return (
<WebView
// source={require('../../Static.bundle/index.html')}
source={{ uri: source }}
// source={{uri:'https://m.baidu.com'}}
style={styles.container}
onLoad={() => {
console.log('webview onLoad')
}}
onLoadEnd={() => {
console.log('webview onLoadEnd')
}}
onLoadStart={() => {
console.log('wenview onLoadStart')
}}
onMessage={event => {
console.log('===>接收到的消息', event.nativeEvent.data)
this.onMessageHandle(event.nativeEvent.data)
// 發(fā)送消息給HTML
this.sendMessageToHtml(event.nativeEvent.data)
}}
originWhitelist={['*']}//解決iOS無法打開bundle里面的html問題 中文亂碼顯示的問題
javaScriptEnabled={true}
ref={webview => this.webview = webview}
/>
)
}
}
3.html改造
在js里面增加方法,使用此方法向react-native傳遞消息
window.ReactNativeWebView.postMessage()
接收來react-native的數(shù)據(jù) 最好兩個(gè)都寫上
window.addEventListener('message', function (e) {//注冊(cè)事件 接收數(shù)據(jù)
const message = e.data;//字符串類型
console.log('WebView message:', message);
alert(message);
})
document.addEventListener('message', function (e) {//注冊(cè)事件 接收數(shù)據(jù)
const message = e.data;//字符串類型
console.log('WebView message:', message);
alert(message);
})
完整react代碼
import React, { Component } from 'react'
import { StyleSheet, Dimensions, NativeModules, NativeEventEmitter,Alert } from 'react-native'
import WebView from 'react-native-webview'
const CalendarManager = NativeModules.CalendarManager
//接收來自原生app的消息
const calendarManagerEmitter = new NativeEventEmitter(CalendarManager);
const subscription = calendarManagerEmitter.addListener(
'EventReminder',
(reminder) => {
console.log("===>接收到來自原生app的消息", reminder.name),
Alert.alert(reminder.name)
}
);
export default class MyWebview extends Component {
constructor() {
super()
// this.sendMessageToHtml = this.sendMessageToHtml.bind(this)
}
// sendMessageToHtml = (data)=>{
// setTimeout(() => {
// console.log('===>需要傳送的data',data)
// this.webview.postMessage(JSON.stringify(data))
// }, 2000);
// }
// onMessageHandle =(data)=>{
// console.log('===>',data)
// let obj = JSON.parse(data)
// console.log('===>obj',obj)
// if(obj.home === 'userCamara'){
// this.props.navigation.navigate('swiper')
// }
// }
//發(fā)送消息給HTML
sendMessageToHtml = (data) => {
setTimeout(() => {
console.log('===>需要傳送的data', data)
this.webview.postMessage(JSON.stringify(data))
}, 2000);
}
//HTML 向 react-native發(fā)送消息
onMessageHandle = (data) => {
console.log('===>', data)
let obj = JSON.parse(data)
console.log('===>obj', obj)
// if(obj.home === 'userCamara'){
if (obj.type === '0') {
this.props.navigation.navigate(obj.home)
} else {
console.log('===>type', obj.type)
this.sendMessageToOC(obj)
}
// }
}
//發(fā)消息給OC
sendMessageToOC = (data) => {
CalendarManager.addDic('生日派對(duì)',
data,
(error, events) => {
if (error) {
// alert(error)
} else {
// alert(events)
}
}
)
}
render() {
let source = (Platform.OS === 'android' ? 'file:///android_asset/' : '') + `Static.bundle/index.html`;
return (
<WebView
// source={require('../../Static.bundle/index.html')}
source={{ uri: source }}
// source={{uri:'https://m.baidu.com'}}
style={styles.container}
onLoad={() => {
console.log('webview onLoad')
}}
onLoadEnd={() => {
console.log('webview onLoadEnd')
}}
onLoadStart={() => {
console.log('wenview onLoadStart')
}}
onMessage={event => {
console.log('===>接收到的消息', event.nativeEvent.data)
this.onMessageHandle(event.nativeEvent.data)
this.sendMessageToHtml(event.nativeEvent.data)
}}
originWhitelist={['*']}//解決iOS無法打開bundle里面的html問題 中文亂碼顯示的問題
javaScriptEnabled={true}
ref={webview => this.webview = webview}
/>
)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
width: Dimensions.get('window').width,
height: Dimensions.get('window').height
}
})
html代碼
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel='stylesheet' type="text/css" href="./html.css" />
<link rel='stylesheet' type='text/css' href="./iconfont.css">
</head>
<body>
<div class="bodyContainer">
<!-- <h1>測(cè)試demo</h1> -->
<div id="container" class="itemContainer">
<!-- <div class="itemStyles" onclick="onclick1(this,'camera')">
<img src="./images/xiangce.png" alt="" width="80px" height="80px" />
<div>調(diào)起相機(jī)</div>
</div> -->
</div>
<script>
const imageArray = [
{
imageName: './images/xiangji1fill.png',
title: '調(diào)用相機(jī)',
stackName: 'camera',
type:'0',
},
{
imageName: './images/shouyelunbotu.png',
title: '輪播圖',
stackName: 'swiper',
type:'0',
},
{
imageName: './images/save-s.png',
title: '本地存儲(chǔ)',
stackName: 'localAysncStorage',
type:'0',
},
{
imageName: './images/wangyesheji.png',
title: '加載網(wǎng)頁',
stackName: 'webview',
type:'0',
},
{
imageName: './images/xiangce.png',
title: '選擇圖片',
stackName: 'pickerImage',
type:'0',
},
{
imageName: './images/dingwei.png',
title: '獲取定位',
stackName: 'location',
type:'0',
},
{
imageName: './images/dingwei.png',
title: '百度OCR',
stackName: 'calendar',
type:'1',
},
{
imageName: './images/dingwei.png',
title: '指紋鎖',
stackName: 'calendar',
type:'2',
},
{
imageName: './images/dingwei.png',
title: '基座版本',
stackName: 'calendar',
type:'3',
},
{
imageName: './images/dingwei.png',
title: '設(shè)備信息',
stackName: 'calendar',
type:'4',
},
{
imageName: './images/dingwei.png',
title: '狀態(tài)欄高度',
stackName: 'calendar',
type:'5',
},
{
imageName: './images/dingwei.png',
title: '開始采集語音',
stackName: 'calendar',
type:'6',
},
{
imageName: './images/dingwei.png',
title: '采集語音',
stackName: 'calendar',
type:'7',
},
{
imageName: './images/dingwei.png',
title: '二維碼',
stackName: 'calendar',
type:'8',
},
{
imageName: './images/dingwei.png',
title: '注冊(cè)人臉',
stackName: 'calendar',
type:'9',
},
{
imageName: './images/dingwei.png',
title: '驗(yàn)證人臉',
stackName: 'calendar',
type:'10',
},
{
imageName: './images/dingwei.png',
title: '刪除人臉',
stackName: 'calendar',
type:'11',
},
]
var htmlElements = "";
console.log('===>', imageArray.length)
for (var i = 0; i < imageArray.length; i++) {
let item = imageArray[i]
console.log('===>', item.title, item)
htmlElements += `<div id='container'><div class='itemStyles' onclick="onclick1(this,'${item.stackName}','${item.type}')"><img src='${item.imageName}' alt='' width='45px' height='45px' /><div>${item.title}</div></div></div>`;
}
var container = document.getElementById("container");
container.innerHTML = htmlElements;
</script>
</div>
</body>
</html>
<script>
onclick1 = (obj, stackName,type) => {
console.log(obj, stackName ,type)
window.ReactNativeWebView.postMessage(JSON.stringify({
home: stackName,
type:type
}));
}
window.addEventListener('message', function (e) {//注冊(cè)事件 接收數(shù)據(jù)
const message = e.data;//字符串類型
console.log('WebView message:', message);
alert(message);
})
document.addEventListener('message', function (e) {//注冊(cè)事件 接收數(shù)據(jù)
const message = e.data;//字符串類型
console.log('WebView message:', message);
alert(message);
})
function jsToOC(name) {
window.webkit.messageHandlers.jsToOC.postMessage({"params":name});
}
</script>
css
.bodyContainer{
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.itemContainer{
display: flex;
flex-direction: row;
justify-content: start;
flex-wrap: wrap;
}
.itemStyles{
display: flex;
flex-direction: column;
width: 23vw;
height: 110px;
justify-content: center;
align-items: center;
text-align: center;
font-size: 12px;
}
react-native 與原生OC的交互:http://www.reibang.com/p/5a5d3995ae31