Flutter对话框对齐插件aligned_dialog的使用

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

Flutter对话框对齐插件aligned_dialog的使用

aligned_dialog简介

aligned_dialog 是一个Flutter包,它允许你打开一个与关联的小部件对齐的对话框。默认情况下,Flutter中的showDialog函数会将对话框居中显示在屏幕上,这在大屏幕设备上可能不是最理想的行为。而aligned_dialog插件则提供了更加灵活的对话框对齐方式。

使用方法

函数接口

以下是showAlignedDialog函数的接口:

Future<T?> showAlignedDialog<T>({
  required BuildContext context,
  required WidgetBuilder builder,
  bool barrierDismissible = true,
  Color? barrierColor = Colors.black54,
  String? barrierLabel,
  bool useRootNavigator = true,
  RouteSettings? routeSettings,
  Alignment followerAnchor = Alignment.center,
  Alignment targetAnchor = Alignment.center,
  Offset offset = Offset.zero,
  bool avoidOverflow = false,
  bool isGlobal = false,
  RouteTransitionsBuilder? transitionsBuilder,
  Duration? duration,
})

其中最后七个参数是与内置showDialog函数不同的地方:

  • followerAnchortargetAnchor 决定了对话框和原始小部件的对齐方式。
  • offset 提供了额外的微调控制。
  • avoidOverflow 设置为true时,对话框会尽可能地调整位置以避免绘制到屏幕外。
  • isGlobal 如果设置为true,则对话框相对于整个屏幕对齐,此时targetAnchor参数无关紧要。
  • transitionsBuilder 定义了对话框出现和消失的方式,默认是一个淡入淡出效果,但可以轻松添加更多动画如滑动等。
  • duration 指定了过渡动画的时间长度。

示例代码

以下是一个完整的示例demo,展示了如何使用aligned_dialog创建不同类型的对话框和抽屉:

import 'dart:math';
import 'package:aligned_dialog/aligned_dialog.dart';
import 'package:flutter/material.dart';

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

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

class MyHomePage extends StatefulWidget {
  MyHomePage({Key? key, required this.title}) : super(key: key);
  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Container(
          width: MediaQuery.of(context).size.width * 0.8,
          child: SingleChildScrollView(
            child: Column(
              children: [
                SizedBox(height: 20,),
                ElevatedButton(
                  onPressed: () {
                    showAlignedDialog(
                      context: context,
                      builder: _localDialogBuilder,
                      followerAnchor: Alignment.topLeft,
                      targetAnchor: Alignment.bottomLeft,
                      barrierColor: Colors.transparent,
                    );
                  },
                  child: Text("Tap to show a local dialog"),
                ),
                SizedBox(height: 20,),
                MouseRegion(
                  onEnter: (event) {
                    showAlignedDialog(
                      context: context,
                      builder: _localDialogBuilder,
                      followerAnchor: Alignment.topLeft,
                      targetAnchor: Alignment.bottomLeft,
                      barrierColor: Colors.transparent,
                    );
                  },
                  child: Container(
                    width: 200,
                    height: 60,
                    color: Colors.orange,
                    child: Center(child: Text("Hover to show a local dialog")),
                  ),
                ),
                SizedBox(height: 20,),
                GestureDetector(
                  onTap: () {
                    showAlignedDialog(
                      context: context,
                      builder: (context) {
                        return Container(
                          decoration: BoxDecoration(
                            border: Border.all(color: Colors.black87, width: 5)
                          ),
                          child: Column(
                            mainAxisSize: MainAxisSize.min,
                            children: [
                              Container(
                                width: 300,
                                height: 180,
                                decoration: BoxDecoration(
                                  image: DecorationImage(
                                    fit: BoxFit.cover,
                                    image: NetworkImage("https://images.unsplash.com/photo-1612392062422-ef19b42f74df?ixid=MnwxMjA3fDF8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=2550&q=80")
                                  )
                                ),
                              ),
                              Container(
                                width: 300,
                                padding: EdgeInsets.symmetric(vertical: 10),
                                child: Text("Enlarged Image"),
                                color: Colors.amberAccent,
                                alignment: Alignment.center,
                              )
                            ],
                          ),
                        );
                      },
                      followerAnchor: Alignment.topLeft,
                      targetAnchor: Alignment.bottomLeft,
                      barrierColor: Colors.transparent,
                    );
                  },
                  child: Container(
                    decoration: BoxDecoration(
                      image: DecorationImage(
                        fit: BoxFit.cover,
                        image: NetworkImage("https://images.unsplash.com/photo-1612392062422-ef19b42f74df?ixid=MnwxMjA3fDF8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=2550&q=80")
                      )
                    ),
                    alignment: Alignment.centerLeft,
                    width: 150,
                    height: 200,
                  ),
                ),
                SizedBox(height: 20,),
                ElevatedButton(
                  onPressed: () {
                    showAlignedDialog(
                      context: context,
                      builder: (context) {
                        return AlertDialog(
                          insetPadding: EdgeInsets.zero,
                          title: Text("Alert!"),
                          content: Text("Its an alert"),
                        );
                      },
                      isGlobal: true,
                      followerAnchor: Alignment.center,
                      targetAnchor: Alignment.bottomLeft,
                      barrierColor: Colors.transparent,
                    );
                  },
                  child: Text("Tap to show a global alert dialog"),
                ),
                SizedBox(height: 20,),
                ElevatedButton(
                  onPressed: () {
                    showGlobalDrawer(
                      context: context,
                      builder: _horizontalDrawerBuilder,
                      direction: AxisDirection.left,
                    );
                  },
                  child: Text("Tap to show a left drawer"),
                ),
                SizedBox(height: 20,),
                ElevatedButton(
                  onPressed: () {
                    showGlobalDrawer(
                      context: context,
                      builder: _horizontalDrawerBuilder,
                      direction: AxisDirection.right,
                    );
                  },
                  child: Text("Tap to show a right drawer"),
                ),
                SizedBox(height: 20,),
                ElevatedButton(
                  onPressed: () {
                    showGlobalDrawer(
                      context: context,
                      builder: _verticalDrawerBuilder,
                      direction: AxisDirection.up,
                    );
                  },
                  child: Text("Tap to show a top drawer"),
                ),
                SizedBox(height: 20,),
                ElevatedButton(
                  onPressed: () {
                    showGlobalDrawer(
                      context: context,
                      builder: _verticalDrawerBuilder,
                      direction: AxisDirection.down,
                    );
                  },
                  child: Text("Tap to show a bottom drawer"),
                ),
                SizedBox(height: 20,),
                Container(
                  height: 100,
                  child: ListView(
                    scrollDirection: Axis.horizontal,
                    children: List.generate(
                      10,
                      (index) => Padding(
                        padding: const EdgeInsets.all(8.0),
                        child: ElevatedButton(
                          onPressed: () {
                            showAlignedDialog(
                              context: context,
                              builder: _localDialogBuilder,
                              followerAnchor: Alignment.topLeft,
                              targetAnchor: Alignment.bottomLeft,
                              barrierColor: Colors.transparent,
                              avoidOverflow: true,
                            );
                          },
                          child: Text("Tap to show a local dialog"),
                        ),
                      ),
                    ),
                  ),
                ),
                ...List.generate(
                  5,
                  (index) => Container(
                    alignment: Alignment.center,
                    padding: const EdgeInsets.all(8.0),
                    child: ElevatedButton(
                      onPressed: () {
                        showAlignedDialog(
                          context: context,
                          builder: _localDialogBuilder,
                          followerAnchor: Alignment.topLeft,
                          targetAnchor: Alignment.bottomRight,
                          barrierColor: Colors.transparent,
                          avoidOverflow: true,
                        );
                      },
                      child: Container(
                        alignment: Alignment.center,
                        width: Random().nextInt(300) + 300,
                        height: Random().nextInt(50) + 50,
                        child: Text("Tap to show a local dialog at bottom right"),
                      ),
                    ),
                  ),
                ),
                ...List.generate(
                  15,
                  (index) => Container(
                    alignment: Alignment.center,
                    margin: EdgeInsets.all(8),
                    child: ElevatedButton(
                      onPressed: () {
                        showAlignedDialog(
                          context: context,
                          builder: _localDialogBuilder,
                          followerAnchor: Alignment.bottomRight,
                          targetAnchor: Alignment.topLeft,
                          barrierColor: Colors.transparent,
                          avoidOverflow: true,
                        );
                      },
                      child: Container(
                        margin: EdgeInsets.all(Random().nextInt(100).toDouble()),
                        alignment: Alignment.center,
                        width: Random().nextInt(300) + 300,
                        height: Random().nextInt(80) + 20,
                        child: Text("Tap to show a local dialog at top left"),
                      ),
                    ),
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }

  WidgetBuilder get _localDialogBuilder {
    return (BuildContext context) {
      return GestureDetector(
        onTap: () {
          Navigator.of(context).pop();
        },
        child: Container(
          padding: EdgeInsets.symmetric(horizontal: 10),
          decoration: BoxDecoration(
            color: Colors.amberAccent,
            borderRadius: BorderRadius.all(Radius.circular(10))
          ),
          child: DefaultTextStyle(
            style: TextStyle(fontSize: 18, color: Colors.black87),
            child: IntrinsicWidth(
              child: Column(
                mainAxisSize: MainAxisSize.min,
                children: [
                  SizedBox(height: 10,),
                  GestureDetector(
                    onTap: () {
                      Navigator.of(context).pop();
                    },
                    child: Text("Tap to close"),
                  ),
                  SizedBox(height: 10,),
                  Divider(height: 4,),
                  SizedBox(height: 10,),
                  GestureDetector(
                    onTap: () {
                      print("hello2");
                    },
                    child: Text("Tap to print"),
                  ),
                  SizedBox(height: 10,),
                ],
              ),
            ),
          ),
        ),
      );
    };
  }

  WidgetBuilder get _horizontalDrawerBuilder {
    return (BuildContext context) {
      return GestureDetector(
        onTap: () {
          Navigator.of(context).pop();
        },
        child: Drawer(
          child: Container(
            width: 400,
            padding: EdgeInsets.symmetric(horizontal: 10),
            decoration: BoxDecoration(
              color: Colors.amberAccent,
            ),
            child: DefaultTextStyle(
              style: TextStyle(fontSize: 18, color: Colors.black87),
              child: IntrinsicWidth(
                child: Column(
                  mainAxisSize: MainAxisSize.max,
                  mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                  children: [
                    SizedBox(height: 10,),
                    GestureDetector(
                      onTap: () {
                        Navigator.of(context).pop();
                      },
                      child: Text("Tap to close"),
                    ),
                    SizedBox(height: 10,),
                    Divider(height: 4,),
                    SizedBox(height: 10,),
                    GestureDetector(
                      onTap: () {
                        print("hello2");
                      },
                      child: Text("Tap to print"),
                    ),
                    SizedBox(height: 10,),
                    Text("Some Text"),
                    SizedBox(height: 10,),
                    Text("Some Text"),
                    SizedBox(height: 10,),
                    Text("Some Text"),
                  ],
                ),
              ),
            ),
          ),
        ),
      );
    };
  }

  WidgetBuilder get _verticalDrawerBuilder {
    return (BuildContext context) {
      return GestureDetector(
        onTap: () {
          Navigator.of(context).pop();
        },
        child: Container(
          height: 300,
          padding: EdgeInsets.symmetric(horizontal: 10),
          decoration: BoxDecoration(
            color: Colors.amberAccent,
          ),
          alignment: Alignment.center,
          child: DefaultTextStyle(
            style: TextStyle(fontSize: 18, color: Colors.black87),
            child: SingleChildScrollView(
              child: Column(
                mainAxisSize: MainAxisSize.min,
                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                children: [
                  SizedBox(height: 10,),
                  GestureDetector(
                    onTap: () {
                      Navigator.of(context).pop();
                    },
                    child: Text("Tap to close"),
                  ),
                  SizedBox(height: 10,),
                  Divider(height: 4,),
                  SizedBox(height: 10,),
                  GestureDetector(
                    onTap: () {
                      print("hello2");
                    },
                    child: Text("Tap to print"),
                  ),
                  SizedBox(height: 10,),
                  Text("Some Text"),
                  SizedBox(height: 10,),
                  Text("Some Text"),
                  SizedBox(height: 10,),
                  Text("Some Text"),
                ],
              ),
            ),
          ),
        ),
      );
    };
  }
}

这个例子包括了按钮点击、悬停触发对话框、图片放大查看、全局对话框以及四个方向的抽屉等功能,通过这些功能你可以更好地理解aligned_dialog的使用场景和灵活性。希望这段代码对你有所帮助!


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

1 回复

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


当然,下面是一个关于如何在Flutter项目中使用aligned_dialog插件来创建对齐对话框的示例代码。这个插件允许你创建一个自定义对齐的对话框,而不仅仅是居中显示。

首先,你需要在你的pubspec.yaml文件中添加aligned_dialog依赖:

dependencies:
  flutter:
    sdk: flutter
  aligned_dialog: ^x.y.z  # 请替换为最新版本号

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

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

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Aligned Dialog Example'),
        ),
        body: Center(
          child: ElevatedButton(
            onPressed: () => showAlignedDialog(context),
            child: Text('Show Aligned Dialog'),
          ),
        ),
      ),
    );
  }

  Future<void> showAlignedDialog(BuildContext context) async {
    // 创建对话框内容
    Widget dialogContent = Column(
      mainAxisSize: MainAxisSize.min,
      children: <Widget>[
        Text('This is a custom aligned dialog!'),
        ElevatedButton(
          onPressed: () => Navigator.of(context).pop(),
          child: Text('Close'),
        ),
      ],
    );

    // 显示对齐对话框
    await showDialog<void>(
      context: context,
      builder: (BuildContext context) {
        return AlignedDialog(
          alignment: Alignment.topRight,  // 对齐方式,这里设置为右上角
          child: Padding(
            padding: const EdgeInsets.all(16.0),
            child: Material(
              type: MaterialType.card,
              elevation: 4.0,
              child: dialogContent,
            ),
          ),
        );
      },
    );
  }
}

在这个示例中:

  1. 我们创建了一个简单的Flutter应用,其中包含一个按钮。
  2. 当按钮被点击时,showAlignedDialog函数被调用。
  3. showAlignedDialog函数使用showDialog来显示一个AlignedDialog
  4. AlignedDialogalignment属性用于设置对话框的对齐方式,这里我们设置为Alignment.topRight,表示对话框将显示在屏幕的右上角。
  5. 对话框的内容是一个简单的Column,包含一个文本和一个关闭按钮。

你可以根据需要调整alignment属性,以实现不同的对齐效果(例如Alignment.bottomLeftAlignment.center等)。希望这个示例能帮助你理解如何在Flutter中使用aligned_dialog插件。

回到顶部