カテゴリー・パッケージ・リポジトリを検索

パッケージ詳細v0.0.1

multi_app_viewer

異なる設定で1つのアプリを同時に表示およびナビゲートするためのツール

AndroidiOSWebmacOSWindowsLinux
30日間ダウンロード
7
いいね数
47
Pub ポイント
130

パッケージをインストール

flutter pub add multi_app_viewer

パッケージ概要

公開情報に基づく選定ガイドです。参考としてご利用ください。

マルチアプリビューアは、開発者が異なる設定で1つのアプリを同時に表示・ナビゲートできるテストツールであり、さまざまな設定での動作の迅速な比較を可能にします。Android、iOS、Web、macOS、Windows、Linuxなど複数のプラットフォームをサポートしており、クロスプラットフォームテストに最適です。このツールは、各設定変更ごとにアプリを再ビルドまたは再起動する必要を減らすことで、開発効率を向上させます。Flutter Pub経由でシームレスに統合され、開発およびQAワークフロー向けに設計されています。

用途

  • 異なるテーマにおけるUI/UXの比較
  • さまざまな環境設定でアプリケーションの動作をテストする
  • 言語間のローカライズ変更の検証
  • プラットフォーム固有のレンダリング問題のデバッグ
  • 開発中の迅速な設定イテレーションの実行

主な機能

  • リアルタイムアプリ状態の切り替え
  • 複数のデバイスプラットフォームのサポート
  • 設定の差異のライブプレビュー
  • Flutter Pub を通じた簡単な統合
  • アプリインスタンス間の組み込みナビゲーション

適している対象

  • Flutter開発者
  • QA テスター
  • UI/UXデザイナー
  • クロスプラットフォームアプリチーム
  • 迅速なプロトタイピング環境

注意事項

  • 本番ビルドには適していません
  • 構成プロファイルの手動設定が必要です
  • 複数のインスタンスでメモリ使用量が増加する可能性があります
  • 閲覧のみ;自動テストには非対応
  • 開発専用の環境でのみ最適に使用される

元の README

関連するソースリポジトリの README 原文のスナップショットです。最新の内容はリポジトリをご覧ください。

Multi App Viewer

Multi App View is a developer tool to view and navigate multiple instances of one app with different visual settings, at the same time.

Multi mode

Web demo

Scenarios:

  • easy and fast visual check of form factors and themes while developing
  • showcasing responsive/adaptive apps
  • self-service screenshots and animations creation
  • design comparison and selection

Why?

  • Lot of time and tons of boring repeating clicks spared by having multiple configurations visible
  • Cool to see and capture several synchronized screens

Features

  • show instances in row, column, stack or complex dashboard layouts
  • navigate all instances together according to the master instance
  • formatting, titles, comments, tilting
  • state broadcast
Presentation features
  • Full screen on/off
  • Hide/show the app bar
  • Preferred configuration list
  • Text only instances: you can add HTML content to highlight certain topics without the app screen
Scripting
  • Autostart and button click scripts
  • Synchronized navigation, event broadcast and configuration change
  • Auto-repeat option
Screenshot and screen-capture
  • Save screenshots of the frame (excluding the MAV appbar)
  • Record screen and convert to animated GIF
Items and configurations

Frame and item configurations

  • in code,
  • save and load config files,
  • edit interactively

Frame configuration

  • Title with HTML support
  • Background color
  • Tilt

Child configuration

  • Title and description with HTML support
  • Device frame
  • Background color
  • Tilt
  • Light or dark mode
  • Directionality (left-to-right, right-to-left)
  • Platform mechanics

Getting started

Add the package to the project

Copy the example/lib/main.dart file with a new name into your project

Replace YourApp() with your top level widget

void main() {
  runApp(const MavCounterDemo());
}

class MavCounterDemo extends StatelessWidget {
  const MavCounterDemo({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        title: 'MAV Demo',
        debugShowCheckedModeBanner: false,
        home: MavFrameWidget(
          itemBuilder: (MavItem mavItem) {
            /* Replace MyApp() with your app widget */
            return YourApp();
          },
        ));
  }
}

Create a new run configuration targeting the new file and run or debug it. You'd see something like this, with your app on the device screens:

First impression

Apps will not run with Multi App View if they are non reentrant.

Usage

Interactive editor

Switch to edit mode on the toolbar and click on an item to configure or click on empty place to open the frame configuration dialog.

Initial view

To change the initial view, add MavFrame.loadConfiguration to the main function

  • selecting one of the predefined configurations
  • creating a configuration from code
  • or loading from file.
void main() {
  MavFrame.loadConfiguration(
    // FrameConfiguration.fromFile('C:\\Users\\kl\\Documents\\mav_config.mavc')
    FrameConfiguration.base(),
  );
  runApp(const MavCounterDemo());
}

While developing and debugging your app, during a hot reload the MAV frame should keep the interactive formatting but on restart it will use the initial view.

Configurations are not app specific, you can reuse them in different projects.

Child customization

Add mavItem parameter to your root widget

class MyApp extends StatelessWidget {
  final MavItem? mavItem;
  MyApp({super.key, this.mavItem});
}

Use mavItem and mainly mavItem.configuration fields to customize each app instance, or add to your own logic based on item index.

MaterialApp.router(
      builder: (context, rootWidget) {
        //use mavItem and mainly mavItem.configuration to customize each app instance
        return Directionality(
          textDirection: item?.configuration.textDirection ?? TextDirection.ltr,
          child: Theme(
              data: Theme.of(context).copyWith(
                  platform: mavItem?.configuration.targetPlatform),
              child: rootWidget!),
        );
      },
//...
)

Synchronized navigation
Common navigation

To navigate all instances according to the master (the first instance) add NavigationObserver


late final GoRouter _router = GoRouter(
  // MAV customization
  // add [mavTtem?.navigatorKey]
  navigatorKey: mavItem?.navigatorKey,
  // add mavItem!.navigatorObserver
  observers:
    mavItem?.navigatorObserver == null ? null : [mavItem!.navigatorObserver],
// ...
);

and an onNavigationCallback to handle and forward navigation events to the rest of the instances. The callback depends on the way of navigation in your app. For example with go_router

    MaterialApp.router(builder: (context, rootWidget) {
        item?.onNavigationCallback =
            (String routeName, int index, {Object? arguments}) {
          if (index != mavItem?.index) {
            if (arguments != null) {
              _router.goNamed(routeName,
                  queryParameters: arguments as Map<String, dynamic>);
            } else {
              _router.goNamed(routeName);
            }
          }
        };
        //...
  })

Customization inside your app

If you want to use MavItem configuration inside the app, you can obtain it via MavItemInherited.

For example, to avoid Android restorationId conflicts:

  late final MavItem? mavItem = MavItemInherited.maybeOf(context)?.item;
  
@override
String get restorationId => 'bottom_app_bar_demo${mavItem?.identifier ?? ''}';
Further synchronization

Multi App Viewer has an entry level event bus. You can push labeled values from one MAV Item, and all others may listen to those values.


  int _counter = 0;
  late final MavItem? mavItem = MavItemInherited.maybeOf(context)?.item;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
    mavItem?.publish('_counterValue', _counter);
  }

  @override
  void dispose() {
    super.dispose();
    mavItem?.dispose('_counterValue');
  }
  
  @override
  Widget build(BuildContext context) {
    mavItem?.listen('_counterValue', (value) {
      setState(() {
        _counter = value;
      });
    });

    return Scaffold(
      //...
    );
  }

If you use a state management solution, the MAV event bus might not be needed. For example, Provider counter example works out of the box when ' Providers are above MyApp instead of inside it. '

Scripts

Scripts are lists of navigation, configuration change and synchronization commands. For example:


   List script = [
    FrameConfiguration.fourPiece(),
    // navigates to details with value 33
     (-1, 'details', {'id1': '33'}),
     // navigates back to main
    (-1, '/', {'id1': '33'}),
    // send value 99 to all listeners
     ('_counterValue', 99)
  ];

   // runs the script when the toolbar menu Run scrip invoked 
   MavFrame.buttonScript = script;

   // runs the script when the app load or reloads 
   MavFrame.autoRunScript = script;
   
  // repeats the script until the stop button is pressed
   MavFrame.autoRepeat = true;

Additional information

Mentions

Although the device_preview package is not used directly, it is still an exceptional inspiration for Flutter development.

The dashboard package is used for complex layouts. That's a very promising solution.

Disclaimer

Showing the same app in multiple slots at the same time is not an end user scenario. Therefore, this is a development tool not a release feature.

Most of the Flutter apps are not reentrant (and that's OK). Running them in parallel with themself has conflicts on statics, globals, keys, local or server resources. These conflicts may result in data loss, endless loops, tricky and hard to detect bugs.

The itemBuilder and the itemInherited permits further customization and isolation of the instances.

Performance degradations are natural as more and more items are started at the same time.

Make sure that Multi App View does not impact the release quality of your app by separating/removing all related code from release builds and have separate run configurations with and without Multi App View.

Screens and platforms

Of course, all instances run on the same platform even if the device frames are different.

Big screen is good. I use the desktop target where I develop.

If you want to make a distributable with the Multi App Viewer, swap the original main.dart file with the new you've created in the Getting Started. Use it internally only, since the Multi App View is not for release versions.

This is a pure dart library, it should work on all platforms - more or less. Multi App Viewer tries to minimize the impact on the hosting app, for example no additional permission are required. That's why the file save/load is a bit simplified...
The config file save and load was not tested on Linux, MacOs and IoS. Please submit an issue if you encounter problems.

Lot of apps will not run with Multi App View if they are non reentrant. For example, in the Gallery App the Reply sample fails on a GlobalKey when running more than one instance, all others work.

Running on different platform may have different results. For example, an app running on Android may fail on restoration ids, but may run on Windows and on Web.

カテゴリー

依存関係

依存関係一覧 9 件

ソースリポジトリ

このパッケージを使用しているプロジェクト

データはまだありません。