我有一个
WebViewClient
的自定义实现,它会覆盖 onPageFinished()
,其中我将加载视图与 WebView
交换。有时一切都很好,但有时 onPageFinished()
根本没有被调用。这是完全随机的。
onPageStarted()
总是接到电话。
public class LoaderWebViewClient extends WebViewClient {
private final TableLayout swapTableLayout;
public LoaderWebViewClient(TableLayout swapTableLayout) {
this.swapTableLayout = swapTableLayout;
}
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
}
// Sometimes doesn't get called
@Override
public void onPageFinished(WebView view, String url) {
swapTableLayout.removeAllViews();
swapTableLayout.addView(view);
super.onPageFinished(view, url);
}
}
我正在从自定义类实例化
WebView
:
WebView webView = new WebView(context);
WebViewClient webViewClient = new LoaderWebViewClient(swapTableLayout);
webView.setWebViewClient(webViewClient);
webView.getSettings().setLoadWithOverviewMode(true);
webView.getSettings().setUseWideViewPort(true);
webView.setVerticalScrollBarEnabled(false);
webView.setHorizontalScrollBarEnabled(false);
webView.getSettings().setJavaScriptEnabled(true);
webView.setOverScrollMode(WebView.OVER_SCROLL_NEVER);
webView.loadUrl(url);
我发现问题了。在
onPageFinished()
中,我将从布局中删除 WebView
本身所在的所有视图(如下一行所示)。
这会以某种方式破坏
WebView
的加载。我刚刚用隐藏和显示视图替换了删除和重新插入视图(它们总是在布局中膨胀),一切似乎都工作正常。
这是 Composable 中带有加载器的完整代码。在此解决方案中,我们还需要一个
if logic
,以免不必要地触发方法onPageFinished
@Composable
fun WebViewContent(link: String) {
var isLoading by remember { mutableStateOf(true) }
var onPageStartedCalled by remember { mutableStateOf(false) }
val scope = rememberCoroutineScope()
val context = LocalContext.current
Box(
modifier = Modifier
.fillMaxSize(),
contentAlignment = Alignment.Center
) {
AndroidView(
factory = {
WebView(context).apply {
layoutParams = ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT
)
var wasCommitCalled = false
webViewClient = object : WebViewClient() {
override fun shouldOverrideUrlLoading(
view: WebView?,
url: String?
): Boolean {
return if (view != null && url != null) {
checkShouldOverrideUrlLoading(view, url)
} else false
}
override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
super.onPageStarted(view, url, favicon)
wasCommitCalled = false
onPageStartedCalled = true
isLoading = true
}
override fun onPageFinished(view: WebView?, url: String?) {
if (onPageStartedCalled) {
scope.launch {
delay(1500)
if (!wasCommitCalled) {
if (url != null) {
loadUrl(url)
}
}
isLoading = false
}
}
}
override fun onPageCommitVisible(view: WebView?, url: String?) {
super.onPageCommitVisible(view, url)
wasCommitCalled = true
}
}
settings.setSupportZoom(true)
settings.builtInZoomControls = true
settings.displayZoomControls = false
settings.javaScriptEnabled = true
settings.useWideViewPort = true
loadUrl("https://drive.google.com/viewerng/viewer?embedded=true&url=$link")
this.setInitialScale(1)
}
},
modifier = Modifier
.fillMaxSize()
.then(Modifier.visibility(!isLoading))
)
LoaderContent(
isLoading = isLoading
)
}
}
@Composable
fun Modifier.visibility(isVisible: Boolean): Modifier {
return if (isVisible) this else alpha(0f)
}
fun checkShouldOverrideUrlLoading(webView: WebView, url: String): Boolean {
webView.loadUrl(url)
if (url.endsWith(".pdf") || url.endsWith(".xlsx") || url.endsWith(".xls") || url.endsWith(".doc") || url.endsWith(
".docx"
) || url.endsWith(".ppt") || url.endsWith(".pptx")
) {
webView.loadUrl("https://docs.google.com/gview?embedded=true&url=$url")
return true
}
return false
}