Skip to content

Software Development at Program Tom LTD

Place for coding, programming, development and software in general.

Menu
  • Blog
  • PDF Booklets
  • Dev Utils & Content
  • Java Spring Boot Or Web Apps
  • English
    • български
    • English
    • Español
    • Português
    • हिन्दी
    • Русский
    • Deutsch
    • Français
    • Italiano
    • العربية
  • About Us
Menu
Flutter Screenshot methods

Flutter Screenshot methods

Posted on October 19, 2025 by Toma Velev

There are several methods you can create screenshots of a Flutter app, depending on whether you want manual screenshots, automated screenshots, or marketing-ready assets. Here’s a breakdown:


📱 1. Manual Screenshots

  • Device Emulator/Simulator
    • Run your app in Android Emulator or iOS Simulator, then use their built-in screenshot tools.
    • Android Studio → Device Manager → Take Screenshot
    • Xcode Simulator → ⌘ + S (or menu → File > New Screenshot)
  • Real Device
    • Run the app on your phone and use the system screenshot shortcut (e.g. Power + Volume Down on Android, Side + Volume Up on iPhone).

🤖 2. Automated Screenshots (for multiple devices/languages)

  • integration_test + screenshots package (deprecated)
    • screenshots plugin lets you automate capturing screenshots for different devices and locales.
    • Useful for app store previews.
    • Runs Flutter integration tests and captures frames programmatically.
  • flutter_driver (deprecated)
    • Older method with flutter_driver, but now replaced by integration_test.

🎨 3. Programmatic Screenshots Inside Flutter

  • RepaintBoundary + RenderRepaintBoundary.toImage()
    • Wrap any widget in a RepaintBoundary and capture it as an image.
    • Example:
      GlobalKey key = GlobalKey();
      
      RepaintBoundary(
        key: key,
        child: MyWidget(),
      );
      
      Future<void> capturePng() async {
        RenderRepaintBoundary boundary =
            key.currentContext!.findRenderObject() as RenderRepaintBoundary;
        var image = await boundary.toImage();
        ByteData? byteData = await image.toByteData(format: ImageByteFormat.png);
        Uint8List pngBytes = byteData!.buffer.asUint8List();
        // Save or share pngBytes
      }
      
    • Great for capturing widgets rather than the whole device screen.

🛠 4. Tools for Marketing Screenshots

  • fastlane + frameit https://docs.fastlane.tools/actions/frameit/
    • Automate generating app store screenshots with device frames.
  • Third-party tools (e.g. Previewed.app, DaVinci, Shotbot)
    • Let you place screenshots into polished device mockups.

👉 Quick recommendation:

  • For simple one-off screenshots → use emulator/device built-in tools.
  • For many locales/devices for app store → use the screenshots package.
  • For in-app widget exports (e.g. custom cards) → use RepaintBoundary.

Instructions for fastlane

✅ You want to capture Flutter app screenshots with Fastlane. That’s a great choice if you’re preparing App Store / Google Play screenshots across devices and languages.

Here’s a step-by-step guide:


🔧 Prerequisites

  1. Install Fastlane (Ruby gem)
    sudo gem install fastlane -NV
    

    Or with brew on macOS:

    brew install fastlane
    
  2. Xcode & Android Studio installed (since Fastlane runs simulators/emulators).
  3. Your Flutter project should have integration tests or flows you want to capture.

📸 Step 1. Add the Fastlane folder

In your Flutter project root:

cd ios
fastlane init

This creates ios/fastlane/ with Fastfile.
Do the same in android/ if you want Play Store automation.


📸 Step 2. Add the snapshot (iOS) / screengrab (Android) plugin

For iOS (Xcode UI tests):

fastlane add_plugin snapshot

For Android (UI Automator tests):

fastlane add_plugin screengrab

📸 Step 3. Configure UI Tests for Screenshots

iOS – snapshot

  1. In ios/RunnerUITests/, create a UI test (Swift):
    import XCTest
    
    class RunnerUITests: XCTestCase {
        func testScreenshot() {
            let app = XCUIApplication()
            setupSnapshot(app)
            app.launch()
    
            // Navigate to screen
            snapshot("01Home")
    
            // Example: tap a button, then capture
            app.buttons["Next"].tap()
            snapshot("02Details")
        }
    }
    
  2. Fastfile lane for iOS:
    lane :ios_screenshots do
      capture_screenshots(
        devices: ["iPhone 14 Pro", "iPad Pro (12.9-inch) (6th generation)"],
        languages: ["en-US", "de-DE"]
      )
    end
    

Android – screengrab

  1. Add screengrab dependency in androidTest:
    androidTestImplementation 'tools.fastlane:screengrab:2.1.1'
    
  2. Example test in android/app/src/androidTest/java/.../MainActivityTest.java:
    import com.facebook.testing.screenshot.Screenshot;
    import tools.fastlane.screengrab.Screengrab;
    import tools.fastlane.screengrab.locale.LocaleTestRule;
    import org.junit.Rule;
    import org.junit.Test;
    
    import static androidx.test.espresso.Espresso.onView;
    import static androidx.test.espresso.matcher.ViewMatchers.withId;
    
    public class MainActivityTest {
        @Rule
        public LocaleTestRule localeTestRule = new LocaleTestRule();
    
        @Test
        public void testTakeScreenshot() {
            Screengrab.screenshot("home_screen");
        }
    }
    
  3. Fastfile lane for Android:
    lane :android_screenshots do
      screengrab(
        locales: ["en-US", "de-DE"],
        devices: ["Pixel_5"],
        clear_previous_screenshots: true
      )
    end
    

📸 Step 4. Run Screenshot Capture

  • iOS:
    cd ios
    fastlane ios ios_screenshots
    
  • Android:
    cd android
    fastlane android android_screenshots
    

This will launch simulators/emulators, run your test flows, and save screenshots.


📸 Step 5. Add Device Frames (Optional, but nice for App Store)

Use frameit:

fastlane frameit

It overlays your screenshots onto Apple device frames.


📂 Where screenshots go

They’ll be stored under:

  • iOS → ios/screenshots/
  • Android → android/fastlane/metadata/android/en-US/images/phoneScreenshots/

You can upload them directly to App Store Connect / Google Play Console.

What are the Flutter way to make screenshots

🖼️ 1. Programmatically capture a widget (best for in-app screenshots)

You can wrap any widget in a RepaintBoundary and convert it to an image:

import 'dart:typed_data';
import 'dart:ui' as ui;
import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';
import 'dart:io';

class ScreenshotExample extends StatefulWidget {
  @override
  _ScreenshotExampleState createState() => _ScreenshotExampleState();
}

class _ScreenshotExampleState extends State<ScreenshotExample> {
  final GlobalKey _globalKey = GlobalKey();

  Future<void> _captureAndSave() async {
    RenderRepaintBoundary boundary =
        _globalKey.currentContext!.findRenderObject() as RenderRepaintBoundary;
    ui.Image image = await boundary.toImage(pixelRatio: 3.0);
    ByteData? byteData =
        await image.toByteData(format: ui.ImageByteFormat.png);
    Uint8List pngBytes = byteData!.buffer.asUint8List();

    final directory = await getApplicationDocumentsDirectory();
    final file = File('${directory.path}/screenshot.png');
    await file.writeAsBytes(pngBytes);

    print("Screenshot saved: ${file.path}");
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("Flutter Screenshot")),
      body: Center(
        child: RepaintBoundary(
          key: _globalKey,
          child: Container(
            padding: EdgeInsets.all(20),
            color: Colors.amber,
            child: Text("Hello Screenshot!"),
          ),
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _captureAndSave,
        child: Icon(Icons.camera),
      ),
    );
  }
}

👉 This captures only the widget inside the RepaintBoundary, not the whole screen.


🖼️ 2. Capture the whole screen

Wrap the entire Scaffold or app in a RepaintBoundary, or use a screenshot package (see below).


🖼️ 3. Use packages

  • screenshot
    Simplifies capturing any widget or screen. Example:

    ScreenshotController screenshotController = ScreenshotController();
    
    Screenshot(
      controller: screenshotController,
      child: MyWidget(),
    );
    
    // Later
    Uint8List image = await screenshotController.capture();
    
  • widgets_to_image
    Similar, but with simpler widget-to-image mapping.
  • flutter_native_screenshot
    Captures the entire screen (not just widgets). Useful if you want a system-level screenshot.

What about with maestro.dev framework

Using Maestro.dev is a modern, Flutter-friendly way to automate screenshots (and UI tests) across devices and languages — similar to Fastlane’s snapshot/screengrab, but simpler and cross-platform.

Let’s go through how to do Flutter screenshots with Maestro step-by-step 👇


🧩 What Maestro Is

Maestro is a lightweight UI testing & automation framework for mobile apps (Android & iOS).
It can:

  • Launch your Flutter app
  • Simulate taps, text inputs, and navigation
  • Capture screenshots programmatically
  • Work in CI pipelines (GitHub Actions, etc.)

⚙️ Step 1: Install Maestro CLI

Run:

curl -Ls "https://get.maestro.mobile.dev" | bash

Then verify:

maestro --version

⚙️ Step 2: Connect Your App

  1. Run your Flutter app in debug or install the .apk/.ipa.
    flutter build apk --debug
    maestro devices
    maestro apps
    

    This lists connected devices and apps (you can get the bundle ID).

  2. Optionally, install the app automatically:
    maestro install build/app/outputs/flutter-apk/app-debug.apk
    

📜 Step 3: Write a Maestro Flow (test script)

Create a folder:

.maestro/
  └── main_flow.yaml

Example (main_flow.yaml):

appId: com.example.myapp
name: Take screenshots of main screens
onFlowStart:
  - clearState
  - launchApp

steps:
  - takeScreenshot: home_screen

  - tapOn: "Next"
  - takeScreenshot: details_screen

  - tapOn: "Profile"
  - takeScreenshot: profile_screen

This script will:

  • Launch your Flutter app
  • Navigate between screens (based on visible text or accessibility labels)
  • Save screenshots automatically

📸 Step 4: Run the Flow

Run:

maestro test .maestro/main_flow.yaml

Screenshots will be saved by default in:

maestro/results/<timestamp>/screenshots/

⚙️ Step 5: (Optional) Multi-language or Device Setup

You can run multiple locales or devices using CLI arguments or in CI:

maestro test .maestro/main_flow.yaml --env LANG=en-US
maestro test .maestro/main_flow.yaml --device "Pixel_5"

In GitHub Actions, you can even generate screenshots for all locales and upload them as artifacts.


💡 Step 6: Add Accessibility IDs in Flutter

Maestro locates widgets by text or accessibility labels.
For robust automation, add Key or semantics labels:

Text('Next', key: Key('nextButton'));

Then Maestro can reliably tap:

- tapOn: "nextButton"

✅ Why Maestro Is Great for Flutter

  • Works seamlessly on Android + iOS
  • No need for native test frameworks (like Espresso/XCUITest)
  • Cross-platform YAML syntax
  • Works well in CI/CD pipelines
  • Can generate consistent screenshots for app stores
  • Side bonus is – better accessibility of your app
  • Feature Flags – Enable Functionality from the BackEnd
  • Integrating xAI Grok API with Spring Boot
  • How to Progresively Integrate AI
  • What is an AI Agent
  • Flutter image scaling

Categories

  • Apps (22)
  • ChatGPT (23)
  • Choosing a Framework (38)
  • Flutter (256)
  • Graphical User Interface (14)
  • Marketing (116)
  • Software Development (281)
  • Spring (44)
  • StartUp (22)
  • Uncategorized (14)
  • Uncategorized (4)
  • Vaadin (14)

Tags

Algorithms (9) crypto (29) flutterdev (39) General (86) Java (7) QR & Bar Codes (3) Software Dev Choices (33) Spring Boot (1) standards (1) Theme (3) User Authentication & Authorization (9) User Experience (10) Utilities (19) WordPress (11)

Product categories

  • All Technologies (84)
    • Flutter Apps (24)
    • GPT (4)
    • Java (38)
    • Native Android (3)
    • PHP (9)
    • Spring (Boot) / Quarkus (35)
    • Utils (15)
    • Vaadin 24+ (27)
    • Vaadin 8 (1)
  • Apps (18)
    • Employees DB (1)
    • Notes (6)
    • Personal Budget (1)
    • Recipes Book (1)
    • Stuff Organizer (1)
    • To-Do (2)
  • PDF Books (3)
  • Source Code Generators (8)

Recent Posts

  • Feature Flags – Enable Functionality from the BackEnd
  • Integrating xAI Grok API with Spring Boot
  • How to Progresively Integrate AI
  • What is an AI Agent
  • Flutter image scaling

Post Categories

  • Apps (22)
  • ChatGPT (23)
  • Choosing a Framework (38)
  • Flutter (256)
  • Graphical User Interface (14)
  • Marketing (116)
  • Software Development (281)
  • Spring (44)
  • StartUp (22)
  • Uncategorized (14)
  • Uncategorized (4)
  • Vaadin (14)