Skip to content

Instantly share code, notes, and snippets.

@yauri-io
Forked from TheMelody/Compose - CustomWebView.kt
Created October 12, 2022 14:04
Show Gist options
  • Save yauri-io/32a1e28bcd5eb55405cde2062f3e43c5 to your computer and use it in GitHub Desktop.
Save yauri-io/32a1e28bcd5eb55405cde2062f3e43c5 to your computer and use it in GitHub Desktop.

Revisions

  1. @TheMelody TheMelody renamed this gist Jun 4, 2021. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  2. @TheMelody TheMelody created this gist Jun 4, 2021.
    76 changes: 76 additions & 0 deletions compose - CustomWebView.kt
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,76 @@
    @Composable
    fun CustomWebView(modifier: Modifier = Modifier,
    url:String,
    onBack: (webView:WebView?) -> Unit,
    onProgressChange: (progress:Int)->Unit = {},
    initSettings: (webSettings:WebSettings?) -> Unit = {},
    onReceivedError: (error: WebResourceError?) -> Unit = {}){
    val webViewChromeClient = object:WebChromeClient(){
    override fun onProgressChanged(view: WebView?, newProgress: Int) {
    //回调网页内容加载进度
    onProgressChange(newProgress)
    super.onProgressChanged(view, newProgress)
    }
    }
    val webViewClient = object: WebViewClient(){
    override fun onPageStarted(view: WebView?, url: String?,
    favicon: Bitmap?) {
    super.onPageStarted(view, url, favicon)
    onProgressChange(-1)
    }
    override fun onPageFinished(view: WebView?, url: String?) {
    super.onPageFinished(view, url)
    onProgressChange(100)
    }
    override fun shouldOverrideUrlLoading(
    view: WebView?,
    request: WebResourceRequest?
    ): Boolean {
    if(null == request?.url) return false
    val showOverrideUrl = request.url.toString()
    try {
    if (!showOverrideUrl.startsWith("http://")
    && !showOverrideUrl.startsWith("https://")) {
    //处理非http和https开头的链接地址
    Intent(Intent.ACTION_VIEW, Uri.parse(showOverrideUrl)).apply {
    addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
    view?.context?.applicationContext?.startActivity(this)
    }
    return true
    }
    }catch (e:Exception){
    //没有安装和找到能打开(「xxxx://openlink.cc....」、「weixin://xxxxx」等)协议的应用
    return true
    }
    return super.shouldOverrideUrlLoading(view, request)
    }

    override fun onReceivedError(
    view: WebView?,
    request: WebResourceRequest?,
    error: WebResourceError?
    ) {
    super.onReceivedError(view, request, error)
    //自行处理....
    onReceivedError(error)
    }
    }
    var webView:WebView? = null
    val coroutineScope = rememberCoroutineScope()
    AndroidView(modifier = modifier,factory = { ctx ->
    WebView(ctx).apply {
    this.webViewClient = webViewClient
    this.webChromeClient = webViewChromeClient
    //回调webSettings供调用方设置webSettings的相关配置
    initSettings(this.settings)
    webView = this
    loadUrl(url)
    }
    })
    BackHandler {
    coroutineScope.launch {
    //自行控制点击了返回按键之后,关闭页面还是返回上一级网页
    onBack(webView)
    }
    }
    }
    45 changes: 45 additions & 0 deletions 调用方法.kt
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,45 @@
    var rememberWebViewProgress: Int by remember { mutableStateOf(-1) }
    Box {
    CustomWebView(
    modifier = Modifier.fillMaxSize(),
    url = "https://www.baidu.com/",
    onProgressChange = { progress ->
    rememberWebViewProgress = progress
    },
    initSettings = { settings ->
    settings?.apply {
    //支持js交互
    javaScriptEnabled = true
    //将图片调整到适合webView的大小
    useWideViewPort = true
    //缩放至屏幕的大小
    loadWithOverviewMode = true
    //缩放操作
    setSupportZoom(true)
    builtInZoomControls = true
    displayZoomControls = true
    //是否支持通过JS打开新窗口
    javaScriptCanOpenWindowsAutomatically = true
    //不加载缓存内容
    cacheMode = WebSettings.LOAD_NO_CACHE
    }
    }, onBack = { webView ->
    if (webView?.canGoBack() == true) {
    webView.goBack()
    } else {
    finish()
    }
    }, onReceivedError = {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    //Log.d("AAAA", ">>>>>>${it?.description}")
    }
    }
    )
    LinearProgressIndicator(
    progress = rememberWebViewProgress * 1.0F / 100F,
    modifier = Modifier
    .fillMaxWidth()
    .height(if (rememberWebViewProgress == 100) 0.dp else 5.dp),
    color = Color.Red
    )
    }