Flutter调用Kotlin实现截图无法正常显示问题求助
问题排查与修复方案
一、核心问题分析
你的代码存在两个关键问题:
- Kotlin端未正确获取Flutter渲染视图,导致截取的是空白或错误的界面内容
- Dart端弹窗内图片容器尺寸过小,即便截图成功也无法正常展示
二、分步修复
1. Kotlin端代码修改
替换原截图逻辑,直接获取Flutter引擎对应的渲染视图,并添加异常处理:
import android.graphics.Bitmap import android.graphics.Canvas import android.os.Bundle import androidx.annotation.NonNull import io.flutter.embedding.android.FlutterActivity import io.flutter.embedding.engine.FlutterEngine import io.flutter.plugin.common.MethodChannel import java.io.ByteArrayOutputStream class MainActivity : FlutterActivity() { private val CHANNEL = "screenshot_channel" override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) { super.configureFlutterEngine(flutterEngine) MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result -> if (call.method == "takeScreenshot") { try { val bitmap = getScreenBitmap(flutterEngine) val byteArray = bitmapToByteArray(bitmap) result.success(byteArray) } catch (e: Exception) { result.error("SCREENSHOT_ERROR", e.message, null) } } else { result.notImplemented() } } } private fun getScreenBitmap(flutterEngine: FlutterEngine): Bitmap { // 获取Flutter实际渲染视图,而非系统rootView val flutterView = flutterEngine.views.first() // 检查视图是否完成布局,避免宽高为0的情况 if (flutterView.width == 0 || flutterView.height == 0) { throw IllegalStateException("Flutter视图尚未完成布局,请稍后重试") } val bitmap = Bitmap.createBitmap(flutterView.width, flutterView.height, Bitmap.Config.ARGB_8888) val canvas = Canvas(bitmap) flutterView.draw(canvas) return bitmap } private fun bitmapToByteArray(bitmap: Bitmap): ByteArray { val stream = ByteArrayOutputStream() bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream) return stream.toByteArray() } }
2. Dart端代码修改
优化弹窗布局尺寸,并添加异常捕获提示:
import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return const MaterialApp( home: Home(), ); } } class Home extends StatelessWidget { const Home({super.key}); static const platform = MethodChannel('screenshot_channel'); Future<Image> _takeScreenshot() async { try { final Uint8List screenshot = await platform.invokeMethod('takeScreenshot'); return Image.memory(screenshot); } on PlatformException catch (e) { throw Exception("截图失败: ${e.message}"); } } @override Widget build(BuildContext context) { return Scaffold( body: Center( child: TextButton( onPressed: () async { try { final capturedImage = await _takeScreenshot(); showCapturedWidget(context, capturedImage); } catch (e) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text(e.toString())), ); } }, child: const Text('截取屏幕'), ), ), ); } } Future<dynamic> showCapturedWidget(BuildContext context, Image? capturedImage) { return showDialog( context: context, builder: (context) => Dialog( child: capturedImage != null ? Container( // 适配屏幕尺寸展示截图 width: MediaQuery.of(context).size.width * 0.8, height: MediaQuery.of(context).size.height * 0.6, child: capturedImage, ) : const Text("截图失败"), ), ); }
内容的提问来源于stack exchange,提问作者sub
相关产品推荐
相关产品推荐

