1

I am planning to replace all the fragments in my project with composables. The only fragment remaining is the one with a WebView in it. I need a way to get it's screenshot whenever user clicks report button

    
Box(Modifier.fillMaxSize()) {

    Button(
        onClick = this@ViewerFragment::onReportClick,
    )

    AndroidView(factory = { context ->
        MyWebView(context).apply {
            loadDataWithBaseURL(htmlString)
                
            addJavascriptInterface(JavaScriptInterface(), "JsIf")
        }
    }
    )
}

Previously; I used to pass the webview from view binding to a utility function for capturing the screenshot.

fun onReportClick() {
    val screenshot = ImageUtil(requireContext()).getScreenshot(binding.myWvViewer)
    .
    .
}

Docs recommend "Constructing the view in the AndroidView viewBlock is the best practice. Do not hold or remember a direct view reference outside AndroidView." So what could be the best approach?

Shreyash.K
  • 487
  • 4
  • 14

1 Answers1

1

Check out this answer on how to take a screenshot of any compose view.

In case you need to take screenshot of the full web view(including not visible part), I'm afraid that's an exceptional case when you have to store in remember variable and pass it into your handler:

var webView by remember { mutableStateOf<WebView?>(null) }
AndroidView(
    factory = { context ->
        WebView(context).apply {
            // ...
            webView = this
        }
    },
)
Button(onClick = {
    onReportClick(webView!!)
}) {
    Text("Capture")
}
Phil Dukhov
  • 67,741
  • 15
  • 184
  • 220
  • Thanks for your answer. I am currently using the second approach which seems to be working fine; but are there any caveats in this approach like a possibility of a memory leak? – Shreyash.K Sep 30 '21 at 18:43
  • 1
    @Shreyash.K `remember` values are bound to the view and should be released when it disappears. In general it should work, unless you move this `remember` from the view that contains `AndroidView`, like storing it in a view model is for sure a bad idea. You should test it to be sure, if you find that the view is not released, it might be a bug, in which case you should report it. There [was an issue](https://issuetracker.google.com/issues/198012639) when `AndroidView` was not released at all, not sure if the fix is included in the latest release, so test without `remember` first. – Phil Dukhov Sep 30 '21 at 19:00
  • I'm trying to screenshot an androidview using this method but it doesn't seem to work on an androidview (all other composables displayed get captured in the image except the androidview) – alfietap Apr 21 '22 at 15:54
  • @alfietap Please create a separate question with a [minimal reproducible example](https://stackoverflow.com/help/minimal-reproducible-example) – Phil Dukhov Apr 22 '22 at 16:22