如何在截图测试中捕获Composable的完整高度?
解决Compose截图测试中长内容被裁剪的问题
当前你使用的captureToImage()方法是基于测试设备的可见屏幕区域捕获画面,所以当Composable高度超过设备高度时,超出部分会被裁剪。要捕获完整的Composable内容,可以通过直接测量Composable的完整尺寸并绘制到对应大小的Bitmap来实现,修改你的ScreenshotTest类如下:
abstract class ScreenshotTest { @get:Rule val rule = createComposeRule() protected fun snapshotComposable( name: String, composable: @Composable () -> Unit, ) { rule.mainClock.autoAdvance = false var fullSize by remember { mutableStateOf(IntSize.Zero) } rule.setContent { Layout( content = composable, measurePolicy = { measurables, _ -> // 测量Composable的完整尺寸,不受屏幕约束限制 val placeable = measurables.first().measure(Constraints()) fullSize = IntSize(placeable.width, placeable.height) layout(placeable.width, placeable.height) { placeable.place(0, 0) } } ) } rule.waitForIdle() // 创建与Composable完整尺寸匹配的Bitmap val fullBitmap = Bitmap.createBitmap( fullSize.width, fullSize.height, Bitmap.Config.ARGB_8888 ) val canvas = Canvas(fullBitmap) // 将整个Composable绘制到Bitmap上 rule.onAllNodes(isRoot()) .onFirst() .drawToCanvas(canvas) fullBitmap.writeToTestStorage(name) } }
关键说明
- 测量完整尺寸:通过自定义
Layout测量Composable的真实尺寸,绕过设备屏幕的约束限制,确保获取到内容的完整宽高。 - 绘制到Bitmap:创建对应尺寸的空白Bitmap,使用
drawToCanvas()方法将整个Composable内容绘制进去,而非仅捕获屏幕可见区域。 - 等待内容就绪:
rule.waitForIdle()确保Composable的布局、绘制流程全部完成,避免截图出现未加载完成的内容。
如果你的Composable包含异步加载的内容(比如网络图片、动画),还需要额外等待对应内容加载完成后再执行截图,比如通过rule.waitUntil()等待特定节点出现。
内容的提问来源于stack exchange,提问作者Billda
相关产品推荐
相关产品推荐

