No Media Query Widget Found

47 views Asked by At

While using the screenshot library in flutter,I used screenshot widget option to capture the image behind the screens however i was met with this error: No MediaQuery ancestor could be found starting from the context that was passed to MediaQuery.of().


  ScreenshotController screenshotController = ScreenshotController();
  await screenshotController
      .captureFromWidget(     Container(
          height: 300,
          width: 500,
          color: Colors.yellow,
          child: Speedometer(data: {"Working": 70, "Average": 10, "Bad": 20, "ItemName": ""}),
        ),)

      .then((Uint8List? value) async {
    speedometerDiagramBytes = value!;
  });


Sppeedometer class is as follows

class Speedometer extends StatelessWidget {
  final Map<String, dynamic> data;

  Speedometer({required this.data});

  @override
  Widget build(BuildContext context) {
    checkDevice(context);
    var height = MediaQuery.of(context).size.height;
    var width = MediaQuery.of(context).size.width;

    double workingValue = data["Working"];
    double averageValue = data["Average"];
    double badValue = data["Bad"];
    String itemName = data["ItemName"];

    return Container(
      height: 100,
      width: 100,
      child: Center(
        child: Stack(
          children: [
           Align(
              alignment: Alignment.center,
              child: CustomPaint(
                size: checkIfLaptop!? Size(450, 450): Size(300,400), // Size of the semi-circle speedometer dial
                painter: SpeedometerPainter(
                  workingValue: workingValue,
                  averageValue: averageValue,
                  badValue: badValue,
                  displayLabel: true
                ),
              ),
            ),
            Positioned(top:  checkIfLaptop!? 10:15, left: checkIfLaptop!? 15:45, child: 
            itemName == "Truck"? Image.asset(truckIcon, 
            height: checkIfDesktop!? 40:30,  
            width: checkIfDesktop!? 40:30,  
            fit: BoxFit.contain,): Image.asset(excavatorIcon,   height: checkIfDesktop!? 40:30,  
            width: checkIfDesktop!? 40:30,  fit: BoxFit.contain,))
          ],
        ),
      ),
    );
  }
}



So far I have tried wrapping it in a material app, adding a scaffold wqith a sized box, but none of them seem to work.

1

There are 1 answers

0
rasityilmaz On

I don't remember how can I solved this error but, I'm use this method.

final class ScreenShotService {
  factory ScreenShotService() {
    return instance;
  }

  ScreenShotService._internal();
  static final ScreenShotService instance = ScreenShotService._internal();

  Future<Uint8List?> takeScreenShotFromWidget({required GlobalKey key, double? aspectRatio}) async {
    try {
      final RenderRepaintBoundary boundaryObject = key.currentContext!.findRenderObject()! as RenderRepaintBoundary;

      final ui.Image image = await boundaryObject.toImage(
        pixelRatio: aspectRatio ?? (16 / 9),
      );

      final ByteData? byteData = await image.toByteData(
        format: ui.ImageByteFormat.png,
      );
      final Uint8List? pngBytes = byteData?.buffer.asUint8List();

      return pngBytes;
    } catch (e) {
      return null;
    }
  }
}

Example usage

import 'dart:ui' as ui;

import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart';

final class ExampleWidget extends StatefulWidget {
  const ExampleWidget({super.key});

  @override
  State<ExampleWidget> createState() => _ExampleWidgetState();
}

class _ExampleWidgetState extends State<ExampleWidget> {
  final GlobalKey _globalKey = GlobalKey();
  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        FlutterLogo(
          key: _globalKey,
        ),
        ElevatedButton(
          onPressed: () async => _takeScreenShot(),
          child: const Text('Take Screenshot'),
        ),
      ],
    );
  }

  Future<void> _takeScreenShot() async {
    try {
      await ScreenShotService().takeScreenShotFromWidget(key: _globalKey).then((value) async {
        if (value != null) {
          ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('Screenshot taken')));
        }
      });
    } catch (e) {}
  }
}