๐Ÿค” does not have many important points, but mainly provides you with information about how to use webView in Compose

1. Initialize WebViewClient, WebChromeClient, under Android. Webkit

val webViewChromeClient = object:WebChromeClient(){
        override fun onProgressChanged(view: WebView? , newProgress:Int) {
            super.onProgressChanged(view, newProgress)
        }
    }
Copy the code
val webViewClient = object: WebViewClient(){
  // Copy some methods. }Copy the code

2. Factory in AndroidView returns WebView

AndroidView(modifier = modifier,factory = { ctx ->
        WebView(ctx).apply {
            this.webViewClient = webViewClient
            this.webChromeClient = webViewChromeClient
            loadUrl(url)
            // Omit other Settings.....}})Copy the code

3. Create a CustomWebView’s Compose method

@Composable
fun CustomWebView(modifier: Modifier = Modifier,
                  // The network requests the address
                  url:String.// Handle the return event yourself
                  onBack: (webView:WebView?). ->Unit.// Select whether to receive, page address loading progress callback
                  onProgressChange: (progress:Int) - >Unit = {},
                  // Choose whether to set your own WebSettings
                  initSettings: (webSettings:WebSettings?). ->Unit = {},
                  // You choose whether to handle the onReceivedError callback event
                  onReceivedError: (error: WebResourceError?). ->Unit = {})
 
Copy the code

4.CustomWebView internal implementation:

  • WebChromeClient() overwrite: onProgressChanged(), callback onProgressChange(50)
  • WebViewClient() overwrites shouldOverrideUrlLoading(),onReceivedError(), etc
  • Create a BackHandler to call back onBack(webView)

๐Ÿ‘‡๐Ÿ‘‡ The final code for CustomWebView is ๐Ÿ‘‡๐Ÿ‘‡ :

@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) {
            // Callback web content loading progress
            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://")) {
                    // Handle link addresses that do not start with HTTP and HTTPSIntent(Intent.ACTION_VIEW, Uri.parse(showOverrideUrl)).apply { addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) view? .context? .applicationContext? .startActivity(this)}return true}}catch (e:Exception){
                // Not installed and found can open (" XXXX ://openlink.cc...." , "weixin:// XXXXX") protocol application
                return true
            }
            return super.shouldOverrideUrlLoading(view, request)
        }

        override fun onReceivedError(
            view: WebView? , request:WebResourceRequest? , error:WebResourceError?). {
            super.onReceivedError(view, request, error)
            // handle your own....
            onReceivedError(error)
        }
    }
    var webView:WebView? = null
    val coroutineScope = rememberCoroutineScope()
    AndroidView(modifier = modifier,factory = { ctx ->
        WebView(ctx).apply {
            this.webViewClient = webViewClient
            this.webChromeClient = webViewChromeClient
            The webSettings callback allows the caller to set the webSettings configuration
            initSettings(this.settings)
            webView = this
            loadUrl(url)
        }
    })
    BackHandler {
        coroutineScope.launch {
            // After clicking the back button, close the page or return to the previous page
            onBack(webView)
        }
    }
}
Copy the code

5.CustomWebView calls as follows:

OnProgressChange: (progress:Int), initSettings: (webSettings: webSettings?) , onReceivedError: (error: WebResourceError?) All three callbacks are optional and used as needed

var rememberWebProgress: Int by remember { mutableStateOf(-1)}
// Wrap the CustomWebView and LinearProgressIndicator with Box
// The loading progress will be displayed at the top of the page
CustomWebView(modifier = Modifier.fillMaxSize(),
              url = "https://www.baidu.com/", onProgressChange = {progress -> rememberWebProgress = progress }, initSettings = {settings-> settings? .apply {// Support JS interaction
                      javaScriptEnabled = true
                      //....
                    }
                }, onBack = { webView ->
                     // This can be handled as required
                     if(webView? .canGoBack() ==true) {
                         // Return to the previous page
                         webView.goBack()
                      } else {
                         / / close the activity
                         finish()
                      }
                 },onReceivedError = {
                      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                            Log.d(TAG,"> > > > > >${it? .description}")
                       }
                 })
                 
LinearProgressIndicator(
        progress = rememberWebProgress * 1.0 F / 100F,
        color = Color.Red,
        modifier = Modifier
              .fillMaxWidth()
              .height(if (rememberWebProgress == 100) 0.dp else 5.dp))
Copy the code

6. Complete code and call method (go to Github to view)

CustomWebView.kt