背景:偿试用RN的WebView实现简单的浏览器功能,于是第一个想到的就是向后和向前,并且能够准确的通过回调updsateNavigationState来获取当前是否可向前或向后的状态。
问题来了:在实测的过程中,WebView打开baidu.com在里面输入一些关键字搜索进入网页updsateNavigationState并不能很准确的回调状态,状态navState.canGoBack + ", " + navState.canGoForward + ", " + navState.title + ", " + navState.url。着急了~~~
原因:查看了下ReactWebViewManager的源码,竟没有实现doUpdateVisitedHistory,每次页面跳转的时候必走此方法。但onPageFinished并不一定会走~~~updsateNavigationState只在onPageFinished中分发了事件~
解决:
方案一:(懒到没朋友的做法)即然知道原因,好办了。。偿试在doUpdateVisitedHistory方法时调用emitFinishEvent(webView, url); 此方法有实现。。。
可以运行!!!
但是这种方案只是试一下可行性。。。
方案二:正规的做法,还是需要定义JS与Java之间的接口调用,完成回调!!
怎么定义接口呢???
定义1:java端
在ReactWebViewClient (ReactWebViewManager中的内部类)中实现如下:
@Override
public void doUpdateVisitedHistory(WebView view, String url, boolean isReload) {
super.doUpdateVisitedHistory(view, url, isReload);
WritableMap event = createWebViewEvent(view, url);
ReactContext reactContext = (ReactContext) view.getContext();
reactContext.getJSModule(RCTEventEmitter.class).receiveEvent(
view.getId(),
"doUpdateVisitedHistory",
event);
}
定义2:java端
在ReactWebViewManager中实现如下:
@Nullable
@Override
public Map getExportedCustomBubblingEventTypeConstants() {
return MapBuilder.builder()
.put(
"doUpdateVisitedHistory",
MapBuilder.of(
"phasedRegistrationNames",
MapBuilder.of("bubbled", "doUpdateVisitedHistory")))
.build();
}
定义3:js端
在WebView.android.js端实现:
<NativeWebView
doUpdateVisitedHistory={(event) => {
console.log("wangkun--------------" + event.nativeEvent.canGoBack + ", " + event.nativeEvent.canGoForward + ", " + event.nativeEvent.title + ", " + event.nativeEvent.loading);
this.props.doUpdateVisitedHistory && this.props.doUpdateVisitedHistory();
}}/>
实测可行!!
放大招代码下载 |