Flutter サスペンド UI のオーバーレイ コンポーネントをデザインする

APP開発でよく遭遇する開発シナリオ

APP を開発するときに、次の要件に遭遇することがあります。

  • フローティング ホバー ボタン、バブル、またはメニューを既存のページに追加します。
  • グローバル通知またはプロンプト ポップアップを実装します。
  • カスタム ナビゲーション バー、ボトム ナビゲーション、またはタブ バーを作成します。
  • モーダル ダイアログまたは下部のポップアップ メニューを構築します。
  • Flutter バージョンの Toast、任意の位置の PopWindow など、画面上にフローティング ウィンドウを表示します。
  • トーストをカスタマイズします。
  • ページの上部にウィジェットをフローティングします。

    これらのシナリオにはすべて共通の機能があります。つまり、特定の UI を現在の UI 上で一時停止して表示する必要があるということです。フラッターを使用してこれらの効果を実現するには、今日学習する Overlay コンポーネントを導入する必要があります。

オーバーレイの概要

Overlay コンポーネントは、Flutter アプリケーションの既存の UI レイヤーの上に新しいビューまたはインタラクションを追加する必要がある場合に使用できます。オーバーレイを使用すると、1 つ以上のウィジェット (OverlayEntry と呼ばれる) をアプリケーションの既存の UI の上に重ね合わせることができます。
オーバーレイには、OverlayState と OverlayEntry という 2 つの基本コンポーネントが含まれています。OverlayState はすべての OverlayEntry を管理し、OverlayEntry はオーバーレイのコンテンツを定義します。

オーバーレイの使用ルール

  • Overlay オブジェクトを作成します。通常は Overlay.of(context) メソッドを使用して、現在のコンテキストで Overlay オブジェクトを取得します。
  • オーバーレイの子となる 1 つ以上の OverlayEntry オブジェクトを作成します。
  • OverlayEntry を Overlay に追加します。通常は OverlayEntry の insert または add メソッドを使用します。
  • オーバーレイを表示または非表示にする必要がある場合、OverlayEntry の markNeedsBuild メソッドが呼び出され、表示されるウィジェットが build メソッドで定義されます。
    オプション: OverlayEntry の位置、サイズ、レイアウト パラメーターを調整して、オーバーレイの位置とスタイルを制御します。

例えば

以下は、説明するための簡単な例です。この例では、ボタンをクリックするとオーバーレイが開き、FloatingActionButton が表示されることを認識しています。

ソースコード

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Flutter Overlay Example'),
        ),
        body: Center(
          child: ElevatedButton(
            child: Text('Open Overlay'),
            onPressed: () {
              showFloatingButtonOverlay(context);
            },
          ),
        ),
      ),
    );
  }
}

void showFloatingButtonOverlay(BuildContext context) {
  OverlayState? overlayState = Overlay.of(context);
  late OverlayEntry overlayEntry;

  // 创建 OverlayEntry
  overlayEntry = OverlayEntry(
    builder: (BuildContext context) {
      return Positioned(
        top: 100,
        right: 16,
        child: FloatingActionButton(
          onPressed: () {
            // 悬浮按钮被点击
            print('Floating Button Clicked');
            overlayEntry.remove(); // 移除 OverlayEntry
          },
          child: Icon(Icons.add),
        ),
      );
    },
  );

  // 将 OverlayEntry 添加到 Overlay 中
  overlayState?.insert(overlayEntry);
}

実行結果を図に示します。

エラーの例

本来は正しいコードを直接載せたかったのですが、初心者が間違いやすいと思うので、別に載せます。

エラー オーバーレイ ウィジェットが見つかりません

[オーバーレイを開く] ボタンをクリックして、オーバーレイ ウィジェットが見つからないことを報告します。以下に示すように
画像.png

エラーの理由

このエラー メッセージは、Overlay.of(context) メソッドの使用時に Overlay オブジェクトが見つからないために表示されます。

解決

ボタンが正しい BuildContext オブジェクト内にあることを確認してください。上記の例では、ボタンが正しいコンテキストで定義され使用されることを保証するために、ボタンの onPressed コールバックで使用される BuildContext は Scaffold のコンテキストである必要があります。

オーバーレイがアプリケーションのコンポーネント ツリーに適切に配置されていることを確認してください。上の例では、オーバーレイ コンポーネントが正しい階層内にあることを確認するために、マテリアルアプリまたはウィジェットアプリの下にある必要があります。

変更されたソースコード

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: OverlayExample(), // 使用 OverlayExample 作为主页
    );
  }
}

class OverlayExample extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Flutter Overlay Example'),
      ),
      body: Center(
        child: ElevatedButton(
          child: Text('Open Overlay'),
          onPressed: () {
            showFloatingButtonOverlay(context);
          },
        ),
      ),
    );
  }
}

void showFloatingButtonOverlay(BuildContext context) {
  OverlayState? overlayState = Overlay.of(context);
  late OverlayEntry overlayEntry;

  // 创建 OverlayEntry
  overlayEntry = OverlayEntry(
    builder: (BuildContext context) {
      return Positioned(
        top: 100,
        right: 16,
        child: FloatingActionButton(
          onPressed: () {
            // 悬浮按钮被点击
            print('Floating Button Clicked');
            overlayEntry.remove(); // 移除 OverlayEntry
          },
          child: Icon(Icons.add),
        ),
      );
    },
  );

  // 将 OverlayEntry 添加到 Overlay 中
  overlayState?.insert(overlayEntry);
}

効果の例

実行の効果を図に示します。[
画像.png
オーバーレイを開く] ボタンをクリックした後の効果の図は次のとおりです。
画像.png

おすすめ

転載: blog.csdn.net/yikezhuixun/article/details/131283414