flutter_device_preview

repository·master·Indexed 25 days ago

https://github.com/aloisdeniel/flutter_device_preview

A Flutter package that allows developers to approximate how their application looks and performs on various mobile devices from a desktop or tablet environment. It features multi-device preview, orientation control, system configuration simulation (language, dark mode, text scaling), and a plugin system including device_preview_screenshot. The package includes the DeviceFrame widget for physical device simulation and DeviceInfo factories for creating custom generic phones, tablets, laptops, and desktop monitors.

Tokens
8K
Snippets
23
Records
56
Agent score
81%

What's inside flutter_device_preview

  1. Overview of flutter_device_preview features

    master

    flutter_device_preview is a tool for simulating mobile device experiences on a laptop, desktop, or tablet. It allows you to preview your application across various device configurations without needing physical hardware.

    Key capabilities include:

    • Multi-device Preview: Preview any device from any device.
    • Orientation Control: Change the device orientation dynamically.
    • System Configuration Simulation: Simulate dynamic system settings such as language, dark mode, and text scaling factors.
    • Freeform Mode: Use a freeform device with adjustable resolution and safe areas.
    • State Preservation: Keep the application state during previews.
    • Plugin System: Extend functionality with plugins like Screenshot or custom implementations.
  2. Core features of Device Preview

    master

    Device Preview provides a simulated mobile environment with the following capabilities:

    • Device Simulation: Preview any device from any device and change device orientation.
    • Dynamic System Configuration: Simulate changes to language, dark mode, text scaling factor, and more.
    • Freeform Mode: Use a freeform device with adjustable resolution and safe areas.
    • State Preservation: Keep the application state during previews.
    • Plugin System: Extend functionality with plugins like Screenshot or File explorer.
  3. Understand the limitations of Device Preview

    master

    Device Preview is a first-order approximation of how your app looks and feels on a mobile device. It simulates the mobile user experience on a laptop, desktop, or tablet rather than running code on actual mobile hardware.

    Some hardware-specific aspects of mobile devices cannot be simulated. For high-fidelity testing, you should run your app on a real physical device.

  4. Understand the limitations of Device Preview simulation

    master

    Device Preview provides a first-order approximation of how an app looks and feels on a mobile device. It simulates the mobile user experience on a computer (laptop, desktop, or tablet) rather than running your code on actual mobile hardware.

    Important Note: Because it is a simulation, there are aspects of mobile devices that Device Preview cannot replicate. For high-fidelity testing or when in doubt, you should run your application on a real physical device.

  5. Quickstart with DeviceFrame

    master

    To use device_frame, wrap any widget in a DeviceFrame widget. You must provide a device parameter, which can be selected from the available Devices accessors (e.g., Devices.ios.iPhone11).

    Key parameters:

    • device: The specific device mockup to display.
    • isFrameVisible: Boolean to show/hide the device frame.
    • orientation: The Orientation of the device.
    • screen: The widget (your app content) to be displayed inside the frame.
    DeviceFrame(
        device: Devices.ios.iPhone11,
        isFrameVisible: true,
        orientation: Orientation.portrait,
        screen: Container(
            color: Colors.blue,
            child: Text('Hello'),
        ),
    )
  6. Integrate DevicePreview into your Flutter app

    master

    To enable device simulation, you must wrap your app's root widget in DevicePreview and configure your MaterialApp (or equivalent) with specific properties.

    Required Configuration:

    1. Wrap the root of your app with DevicePreview in main().
    2. Set useInheritedMediaQuery to true in your MaterialApp.
    3. Set the builder property to DevicePreview.appBuilder.
    4. Set the locale property to DevicePreview.locale(context).

    Note: If these properties are not overridden as described, MediaQuery will not be simulated for the selected device.

    import 'package:device_preview/device_preview.dart';
    
    void main() => runApp(
      DevicePreview(
        enabled: !kReleaseMode,
        builder: (context) => MyApp(), // Wrap your app
      ),
    );
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          useInheritedMediaQuery: true,
          locale: DevicePreview.locale(context),
          builder: DevicePreview.appBuilder,
          theme: ThemeData.light(),
          darkTheme: ThemeData.dark(),
          home: const HomePage(),
        );
      }
    }
  7. Add DevicePreview to your Flutter app

    master

    To enable device simulation, wrap your app's root widget in DevicePreview and configure your MaterialApp (or equivalent) to use the simulated media queries, locale, and builder provided by the package.

    Required Configuration:

    1. Wrap the root of your app with DevicePreview.
    2. Set useInheritedMediaQuery: true in your MaterialApp.
    3. Set locale: DevicePreview.locale(context) in your MaterialApp.
    4. Set builder: DevicePreview.appBuilder in your MaterialApp.

    Note: If these properties are not overridden as described, MediaQuery will not be simulated for the selected device.

    import 'package:device_preview/device_preview.dart';
    
    void main() => runApp(
      DevicePreview(
        enabled: !kReleaseMode,
        builder: (context) => MyApp(), // Wrap your app
      ),
    );
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          useInheritedMediaQuery: true,
          locale: DevicePreview.locale(context),
          builder: DevicePreview.appBuilder,
          theme: ThemeData.light(),
          darkTheme: ThemeData.dark(),
          home: const HomePage(),
        );
      }
    }
  8. Install the Screenshot plugin

    master

    To use the screenshot functionality in device_preview, add device_preview_screenshot to your pubspec.yaml dependencies and register the DevicePreviewScreenshot plugin within the tools property of your DevicePreview widget.

    dependencies:
      device_preview_screenshot: <latest version>
    import 'package:device_preview_screenshot/device_preview_screenshot.dart';
    
    DevicePreview(
        // ...
        tools: [
            ...DevicePreview.defaultTools,
            const DevicePreviewScreenshot(),
        ],
    ),
  9. Maintain device MediaQuery and theme in an encapsulated app

    master

    When using DeviceFrame, your app inside the screen property might not automatically respect the simulated device's MediaQuery or Theme. To ensure a WidgetsApp (like MaterialApp) uses the simulated device context, set the useInheritedMediaQuery property to true.

    It is recommended to use a Builder to ensure you have the correct context when initializing the MaterialApp.

    DeviceFrame(
        device: Devices.ios.iPhone11,
        orientation: orientation,
        screen: Builder(
            builder: (deviceContext) => MaterialApp(
                useInheritedMediaQuery: true,
                theme: Theme.of(context),
            ),
        ),
    ),
  10. Create a custom plugin for Device Preview

    master

    A plugin is a Sliver widget that is added to the Device Preview menu. To ensure your plugin matches the visual style of built-in sections, wrap your content in a ToolPanelSection widget and use standard package:flutter/material.dart widgets like ListTile.

    import 'package:device_preview/device_preview.dart';
    import 'package:flutter/material.dart';
    
    class CustomPlugin extends StatelessWidget {
      const CustomPlugin({
        Key? key,
      }) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return ToolPanelSection(
          title: 'Screenshot',
          children: [
            ListTile(
              title: const Text('Print in console'),
              onTap: () {
                print('Hey, this is a custom plugin!');
              },
            )
          ],
        );
      }
    }