Flutter对话框定位插件relative_dialog的使用

发布于 1周前 作者 sinazl 来自 Flutter

Flutter对话框定位插件relative_dialog的使用

relative_dialog 是一个用于在Flutter中显示相对于另一个widget的对话框的包。它允许开发者创建与特定widget位置相关的弹出式对话框,提供了更灵活和直观的用户体验。

基本概念

  • RelativeAnchor: 该组件可以包裹需要展示对话框的widget,通过其提供的show函数来触发对话框。
  • Imperative API: 提供了直接调用showRelativeDialog的方法,不需要使用RelativeAnchor,只需要传递相对的BuildContext即可。
  • Custom Animations: 支持自定义动画,可以通过transitionBuilder参数指定对话框出现时的过渡效果。

示例图片

Basic demo gif Basic demo 2 gif

使用方法

使用RelativeAnchor

Builder(
  builder: (context) {
    return RelativeAnchor(
      builder: (
        context, {
        required show,
      }) {
        return ElevatedButton(
          child: Text('Show relative dialog'),
          onPressed: () {
            show(
              // The alignment the dialog should be positioned at relative to widget that opened it.
              alignment: Alignment.topRight,
              builder: (context) {
                return Text(
                  'Done!',
                  style: TextStyle(
                    color: Colors.white,
                  ),
                );
              }
            );
          },
        );
      }
    );
  }
);

使用Imperative API

Builder(
  builder: (context) {
    return ElevatedButton(
      child: Text('Show relative dialog'),
      onPressed: () {
        showRelativeDialog(
          // The context of the widget that the dialog should be shown relative to.
          context: context,
          // The alignment the dialog should be positioned at relative to widget that opened it.
          alignment: Alignment.topRight,
          builder: (context) {
            return Text(
              'Done!',
              style: TextStyle(
                color: Colors.white,
              ),
            );
          }
        );
      },
    );
  }
);

自定义动画

Builder(
  builder: (context) {
    return ElevatedButton(
      child: Text('Show relative dialog'),
      onPressed: () {
        showRelativeDialog(
          context: context,
          alignment: Alignment.bottomRight,
          transitionBuilder: (context, animation, secondaryAnimation, child) =>
            ScaleTransition(
              alignment: Alignment.topRight,
              scale: CurvedAnimation(
                parent: animation,
                curve: Curves.easeOut,
                reverseCurve: Curves.easeIn,
              ),
              child: child,
            ),
          builder: (context) {
            return Text(
              'Done!',
              style: TextStyle(
                color: Colors.white,
              ),
            );
          }
        );
      },
    );
  }
);

完整示例Demo

以下是一个完整的应用示例,展示了如何使用relative_dialog插件:

import 'package:flutter/material.dart';
import 'package:relative_dialog/relative_anchor.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final _alignments = [
    Alignment.bottomLeft,
    Alignment.bottomCenter,
    Alignment.bottomRight,
    Alignment.centerLeft,
    Alignment.center,
    Alignment.centerRight,
    Alignment.topLeft,
    Alignment.topCenter,
    Alignment.topRight,
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: RelativeAnchor(
          builder: (
            context, {
            required show,
          }) {
            return ElevatedButton(
              onPressed: () async {
                if (_alignments.isEmpty) {
                  return show(
                    barrierColor: Colors.transparent,
                    builder: (context) {
                      return Container(
                        alignment: Alignment.center,
                        padding: const EdgeInsets.symmetric(horizontal: 4),
                        color: Colors.green,
                        width: 200,
                        height: 200,
                        child: const Text(
                          'Done!',
                          style: TextStyle(
                            color: Colors.white,
                          ),
                        ),
                      );
                    },
                  );
                }

                final alignment = _alignments.first;
                await show(
                  alignment: alignment,
                  barrierColor: Colors.transparent,
                  builder: (context) {
                    return Container(
                      color: Colors.green,
                      alignment: Alignment.center,
                      padding: const EdgeInsets.symmetric(horizontal: 4),
                      width: 80,
                      height: 80,
                      child: Text(
                        '$alignment',
                        style: const TextStyle(
                          color: Colors.white,
                          fontSize: 10,
                        ),
                      ),
                    );
                  },
                );
                setState(() {
                  _alignments.removeAt(0);
                });
              },
              child: Text(
                _alignments.isEmpty ? 'Done' : 'Next: ${_alignments.first}',
              ),
            );
          },
        ),
      ),
    );
  }
}

这个例子展示了如何通过点击按钮依次展示不同位置的对话框,并且当所有对齐方式都展示完毕后显示一个“Done!”的信息。希望这些信息能够帮助您更好地理解和使用relative_dialog插件。


更多关于Flutter对话框定位插件relative_dialog的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter对话框定位插件relative_dialog的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter项目中使用relative_dialog插件来定位对话框的示例代码。relative_dialog插件允许你相对于屏幕或父组件定位对话框。

首先,确保你已经在你的pubspec.yaml文件中添加了relative_dialog依赖:

dependencies:
  flutter:
    sdk: flutter
  relative_dialog: ^latest_version  # 请替换为实际最新版本号

然后运行flutter pub get来安装依赖。

接下来是一个示例代码,展示如何使用relative_dialog插件:

import 'package:flutter/material.dart';
import 'package:relative_dialog/relative_dialog.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Relative Dialog Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  GlobalKey _dialogKey = GlobalKey();

  void _showDialog() {
    RelativeDialog.show(
      context: context,
      builder: (context) {
        return AlertDialog(
          title: Text('Relative Dialog'),
          content: Text('This dialog is positioned relative to the parent widget.'),
          actions: <Widget>[
            FlatButton(
              child: Text('Close'),
              onPressed: () {
                Navigator.of(context).pop();
              },
            ),
          ],
        );
      },
      key: _dialogKey,
      // Positioning parameters
      alignment: Alignment.topLeft,
      offset: Offset(20, 20),  // Optional, add an offset to the alignment
      parentAnchor: Alignment.topLeft,  // This aligns the dialog relative to the top-left corner of the parent widget
      parentBounds: MediaQuery.of(context).size,  // The bounds of the parent widget
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Relative Dialog Example'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'You can show a dialog relative to its parent widget.',
            ),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: _showDialog,
              child: Text('Show Dialog'),
            ),
          ],
        ),
      ),
    );
  }
}

解释

  1. 依赖导入:首先,我们在pubspec.yaml中添加了relative_dialog依赖。
  2. 对话框显示:使用RelativeDialog.show方法来显示对话框。
  3. 对话框参数
    • context:当前的上下文。
    • builder:构建对话框内容的函数。
    • key:一个GlobalKey,用于唯一标识对话框。
    • alignment:对话框在其父组件中的对齐方式。
    • offset:可选的,用于微调对话框位置。
    • parentAnchor:父组件的锚点,表示对话框相对于父组件的哪个部分对齐。
    • parentBounds:父组件的边界,通常使用MediaQuery.of(context).size来获取。

这个示例展示了如何使用relative_dialog插件在Flutter中创建一个相对于父组件定位的对话框。你可以根据需要调整alignmentoffsetparentAnchor等参数,以达到所需的定位效果。

回到顶部