在 Jetpack Compose 中以编程方式截取可组合乐趣的屏幕截图 [英] Take screenshot of a composable fun programmatically in Jetpack Compose

查看:65
本文介绍了在 Jetpack Compose 中以编程方式截取可组合乐趣的屏幕截图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想将 Jetpack compose 发出的 UI 捕获为位图.在 XML 中,这是这样做的:

I would like to capture the UI emitted by Jetpack compose as a Bitmap. In XML this was done like this:

基本上将视图作为输入参数并将其作为位图返回.

Basically takes a view as an input parameter and returns it as a Bitmap.

//take screenshot of the view added as an input argument
fun takeScreenShot(view: View) : Bitmap {
    val bitmap = Bitmap.createBitmap(
        view.width,
        view.height,
        Bitmap.Config.ARGB_8888
    )
    val canvas = Canvas(bitmap)
    view.draw(canvas)
    return bitmap
}

Jetpack compose 中的 this 是什么?

What is the equivalent of this in Jetpack compose?

推荐答案

测试中可以从组合中截取屏幕截图.
要在生产代码中截取屏幕截图,请参阅这个问题这个问题.

Taking screenshots from a composable is possible in tests.
For taking screenshots in production code see this question and this issue.

首先,确保您的构建脚本中具有以下依赖项(以及其他必需的 Compose 依赖项):

First, make sure you have the following dependency in your build script (along with other required Compose dependencies):

debugImplementation("androidx.compose.ui:ui-test-manifest:<version>")

注意:代替上面的依赖,您可以简单地在 androidTest 目录中添加一个 AndroidManifest.xml 并在 manifest 中添加以下内容code>>application 元素:.
请参阅此答案.

Note: Instead of the above dependency, you can simply add an AndroidManifest.xml in androidTest directory and add the following in manifest>application element: <activity android:name="androidx.activity.ComponentActivity" />.
Refer to this answer.

以下是保存、阅读和比较屏幕截图的完整示例:
(请参考这篇文章设置写权限等测试)

Here is a complete example for saving, reading, and comparing screenshots:
(Please refer to this post for setting up write permissions and so on for the tests)

class ScreenshotTest {

    @get:Rule val composeTestRule = createComposeRule()

    @Test fun takeAndSaveScreenshot() {
        composeTestRule.setContent { MyComposableFunction() }
        val node = composeTestRule.onRoot()
        val screenshot = node.captureToImage().asAndroidBitmap()
        saveScreenshot("screenshot.png", screenshot)
    }

    @Test fun readAndCompareScreenshots() {
        composeTestRule.setContent { MyComposableFunction() }
        val node = composeTestRule.onRoot()
        val screenshot = node.captureToImage().asAndroidBitmap()

        val context = InstrumentationRegistry.getInstrumentation().targetContext
        val path = context.getExternalFilesDir(Environment.DIRECTORY_PICTURES)
        val file = File(path, "screenshot.png")
        val saved = readScreenshot(file)

        println("Are screenshots the same: ${screenshot.sameAs(saved)}")
    }

    private fun readScreenshot(file: File) = BitmapFactory.decodeFile(file.path)

    private fun saveScreenshot(filename: String, screenshot: Bitmap) {
        val context = InstrumentationRegistry.getInstrumentation().targetContext
        // Saves in /Android/data/your.package.name.test/files/Pictures on external storage
        val path = context.getExternalFilesDir(Environment.DIRECTORY_PICTURES)
        val file = File(path, filename)
        file.outputStream().use { stream ->
            screenshot.compress(Bitmap.CompressFormat.PNG, 100, stream)
        }
    }
}

感谢 Google Codelabs 这个.

Thanks to Google Codelabs for this.

这篇关于在 Jetpack Compose 中以编程方式截取可组合乐趣的屏幕截图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆