You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 22:37:47