Flutter多功能对话框插件versatile_dialogs的使用

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

Flutter多功能对话框插件versatile_dialogs的使用

Versatile Dialogs 是一个功能丰富的 Flutter 包,提供了可定制的对话框,用于单值选择和多值选择,包括懒加载和各种自定义选项。

安装插件

要安装此插件,请在终端运行以下命令:

flutter pub add versatile_dialogs

或者,在 pubspec.yaml 文件中添加 versatile_dialogs 并运行:

flutter pub get

使用方法

1. 主对话框

初始化主对话框类

PrimaryDialog primaryDialog = PrimaryDialog(
  key: const Key('primaryDialog'),
  title: '主对话框',
  body: const Padding(
    padding: EdgeInsets.symmetric(vertical: 20.0, horizontal: 10.0),
    child: Text('这是主对话框的描述'),
  ),
  dialogButton: DialogButton(
    context: context,
    positiveButtonName: "确定",
    negativeButtonName: "取消",
  ),
);

显示对话框并获取结果

bool? result = await primaryDialog.show(context);

if(result == null){
  print("点击了对话框外部");
} else if(result){
  print("按下了确定按钮");
} else {
  print("按下了取消按钮");
}

2. 加载对话框

初始化加载对话框类

LoadingDialog loadingDialog = LoadingDialog(message: "正在加载...");

显示对话框

loadingDialog.show(context);

关闭对话框

loadingDialog.dismiss(context);

3. 单值选择对话框

初始化单值选择对话框类

SingleValuePickerDialog<String> singleValuePickerDialog = SingleValuePickerDialog(
  items: ['一', '二', '三', '四', '五', '六'],
  title: '请选择一个值',
  itemBuilder: (context, value) {
    return Padding(
      padding: const EdgeInsets.all(16.0),
      child: Text(value),
    );
  },
  dialogButton: DialogButton(
    context: context,
    negativeButtonKey: const Key('negativeButton'),
    negativeButtonName: '取消',
  ),
);

显示对话框并获取所选项目

String? result = await singleValuePickerDialog.show(context);

if(result != null){
  print("未选择任何值");
} else {
  print("选择的项目 -> $result");
}

4. 多值选择对话框

初始化多值选择对话框类

MultiValuePickerDialog<String> multiSelectableDialog = MultiValuePickerDialog(
  title: '请选择多个值',
  items: ['一', '二', '三', '四', '五', '六'],
  initialSelectedItems: ['三'],
  itemBuilder: (context, value) {
    return Padding(
      padding: const EdgeInsets.all(8.0),
      child: Text(value),
    );
  },
  selectedItemBuilder: (context, value) {
    return Padding(
      padding: const EdgeInsets.all(8.0),
      child: Text(
        value,
        style: const TextStyle(color: Colors.deepPurple),
      ),
    );
  },
  dialogButton: DialogButton(
    context: context,
    positiveButtonName: '选择',
    negativeButtonName: '取消',
  ),
);

显示对话框并获取所选项目

List<String> result = await multiSelectableDialog.show(context) ?? [];

if(result.isEmpty){
  print("未选择任何值");
} else {
  print("选择的项目 -> ${result.join(', ')}");
}

5. 懒加载单值选择对话框

初始化懒加载单值选择对话框类

LazySingleValuePickerDialog<String> dialog = LazySingleValuePickerDialog(
  asyncItems: getAsyncItems,
  itemBuilder: (context, value) => Padding(
    key: Key(value),
    padding: const EdgeInsets.all(8.0),
    child: Text(value),
  ),
  title: '请选择一个值',
  loadingMessage: "正在获取数据...",
  dialogButton: DialogButton(
    context: context,
    negativeButtonName: '取消',
  ),
);

Future<List<String>> getAsyncItems() async {
  await Future.delayed(const Duration(seconds: 2));
  return ['一', '二', '三', '四', '五', '六'];
}

显示对话框并获取所选项目

String? item = await dialog.show(context);

if(item != null){
  print("未选择任何值");
} else {
  print("选择的项目 -> $item");
}

6. 懒加载多值选择对话框

初始化懒加载多值选择对话框类

LazyMultiValuePickerDialog<String> dialog = LazyMultiValuePickerDialog(
  asyncItems: getAsyncItems,
  initialSelectedItems: ['三'],
  itemBuilder: (context, value) {
    return Padding(
      padding: const EdgeInsets.all(8.0),
      child: Text(value),
    );
  },
  title: '请选择多个值',
  dialogButton: DialogButton(
    context: context,
    positiveButtonName: '选择',
    negativeButtonName: '取消',
  ),
);

Future<List<String>> getAsyncItems() async {
  await Future.delayed(const Duration(seconds: 2));
  return ['一', '二', '三', '四', '五', '六'];
}

显示对话框并获取所选项目

List<String> result = await dialog.show(context) ?? [];

if(result.isEmpty){
  print("未选择任何值");
} else {
  print("选择的项目 -> ${result.join(', ')}");
}

完整示例代码

import 'package:flutter/material.dart';
import 'package:versatile_dialogs/common/dialog_buttons.dart';
import 'package:versatile_dialogs/lazy_multi_value_picker_dialog.dart';
import 'package:versatile_dialogs/lazy_single_value_picker_dialog.dart';
import 'package:versatile_dialogs/loading_dialog.dart';
import 'package:versatile_dialogs/multi_value_picker_dialog.dart';
import 'package:versatile_dialogs/primary_dialog.dart';
import 'package:versatile_dialogs/single_value_picker_dialog.dart';

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

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

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: '对话框测试页面',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const VersatileDialogsExample(),
    );
  }
}

class VersatileDialogsExample extends StatefulWidget {
  const VersatileDialogsExample({super.key});

  [@override](/user/override)
  State<VersatileDialogsExample> createState() => _VersatileDialogsExampleState();
}

class _VersatileDialogsExampleState extends State<VersatileDialogsExample> {
  List<String> list = ['一', '二', '三', '四', '五', '六'];

  Future<List<String>> getAsyncItems() async {
    await Future.delayed(const Duration(seconds: 2));
    return ['一', '二', '三', '四', '五', '六'];
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: const Text("多功能对话框示例"),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Padding(
              padding: const EdgeInsets.symmetric(vertical: 10.0),
              child: ElevatedButton(
                onPressed: _showPrimaryDialog,
                child: const Text(
                  '主对话框',
                ),
              ),
            ),
            Padding(
              padding: const EdgeInsets.symmetric(vertical: 10.0),
              child: ElevatedButton(
                onPressed: _showLoadingDialog,
                child: const Text(
                  '加载对话框',
                ),
              ),
            ),
            Padding(
              padding: const EdgeInsets.symmetric(vertical: 10.0),
              child: ElevatedButton(
                onPressed: _showSingleValuePickerDialog,
                child: const Text(
                  '单值选择对话框',
                ),
              ),
            ),
            Padding(
              padding: const EdgeInsets.symmetric(vertical: 10.0),
              child: ElevatedButton(
                onPressed: _showMultiValuePickerDialog,
                child: const Text(
                  '多值选择对话框',
                ),
              ),
            ),
            Padding(
              padding: const EdgeInsets.symmetric(vertical: 10.0),
              child: ElevatedButton(
                onPressed: _showLazySingleValuePickerDialog,
                child: const Text(
                  '懒加载单值选择对话框',
                ),
              ),
            ),
            Padding(
              padding: const EdgeInsets.symmetric(vertical: 10.0),
              child: ElevatedButton(
                onPressed: _showLazyMultiValuePickerDialog,
                child: const Text(
                  '懒加载多值选择对话框',
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }

  void _showPrimaryDialog() async {
    PrimaryDialog primaryDialog = PrimaryDialog(
      title: '主对话框',
      body: const Padding(
        padding: EdgeInsets.symmetric(vertical: 20.0, horizontal: 10.0),
        child: Text('这是主对话框的描述'),
      ),
      dialogButton: DialogButton(
        context: context,
        positiveButtonName: "确定",
        negativeButtonName: "取消",
      ),
    );
    bool? result = await primaryDialog.show(context);

    if (context.mounted) {
      SnackBar snackBar = SnackBar(
        content: Center(
          child: Text(
            result == null
                ? '点击了对话框外部'
                : result
                    ? '按下了确定按钮'
                    : '按下了取消按钮',
          ),
        ),
        behavior: SnackBarBehavior.floating,
      );

      ScaffoldMessenger.of(context)
        ..clearSnackBars()
        ..showSnackBar(snackBar);
    }
  }

  void _showLoadingDialog() async {
    LoadingDialog loadingDialog = LoadingDialog(message: "正在加载...")
      ..show(context);

    Future.delayed(const Duration(seconds: 3)).then((value) {
      loadingDialog.dismiss(context);
      if (context.mounted) {
        SnackBar snackBar = const SnackBar(
          content: Center(
            child: Text("对话框加载了3秒"),
          ),
          behavior: SnackBarBehavior.floating,
        );

        ScaffoldMessenger.of(context)
          ..clearSnackBars()
          ..showSnackBar(snackBar);
      }
    });
  }

  void _showSingleValuePickerDialog() async {
    SingleValuePickerDialog<String> singleValuePickerDialog = SingleValuePickerDialog(
      items: list,
      title: '请选择一个值',
      itemBuilder: (context, value, index) {
        return Padding(
          padding: const EdgeInsets.all(17.0),
          child: Text(value),
        );
      },
      dialogButton: DialogButton(
        context: context,
        negativeButtonName: '取消',
      ),
    );

    String? result = await singleValuePickerDialog.show(context);

    if (context.mounted) {
      SnackBar snackBar = SnackBar(
        content: Center(
          child: Text(
            result != null ? "'$result' 被选择" : "未选择任何值",
          ),
        ),
        behavior: SnackBarBehavior.floating,
      );

      ScaffoldMessenger.of(context)
        ..clearSnackBars()
        ..showSnackBar(snackBar);
    }
  }

  void _showMultiValuePickerDialog() async {
    MultiValuePickerDialog<String> multiSelectableDialog = MultiValuePickerDialog(
      title: '请选择多个值',
      items: list,
      initialSelectedItems: ['三'],
      itemBuilder: (context, value, index) {
        return Padding(
          padding: const EdgeInsets.all(8.0),
          child: Text(value),
        );
      },
      // selectionType: MultiDialogSelectionType.itemTap,
      selectedItemBuilder: (context, value, index) {
        return Padding(
          padding: const EdgeInsets.all(8.0),
          child: Text(
            value,
            style: const TextStyle(color: Colors.deepPurple),
          ),
        );
      },
      dialogButton: DialogButton(
        context: context,
        positiveButtonName: '选择',
        negativeButtonName: '取消',
      ),
    );

    List<String> result = await multiSelectableDialog.show(context) ?? [];

    if (context.mounted) {
      SnackBar snackBar = SnackBar(
        content: Center(
          child: Text(result.isNotEmpty
              ? "'${result.join(', ')}' 被选择"
              : "未选择任何值"),
        ),
        behavior: SnackBarBehavior.floating,
      );

      ScaffoldMessenger.of(context)
        ..clearSnackBars()
        ..showSnackBar(snackBar);
    }
  }

  void _showLazySingleValuePickerDialog() async {
    LazySingleValuePickerDialog<String> dialog = LazySingleValuePickerDialog(
      asyncItems: getAsyncItems,
      itemBuilder: (context, value, index) => Padding(
        padding: const EdgeInsets.all(8.0),
        child: Text(value),
      ),
      loadingMessage: "正在获取数据...",
      title: '请选择一个值',
      dialogButton: DialogButton(
        context: context,
        negativeButtonName: '取消',
      ),
    );

    String? item = await dialog.show(context);

    if (context.mounted) {
      SnackBar snackBar = SnackBar(
        content: Center(
          child: Text(item != null ? "'$item' 被选择" : "未选择任何值"),
        ),
        behavior: SnackBarBehavior.floating,
      );

      ScaffoldMessenger.of(context)
        ..clearSnackBars()
        ..showSnackBar(snackBar);
    }
  }

  void _showLazyMultiValuePickerDialog() async {
    LazyMultiValuePickerDialog<String> dialog = LazyMultiValuePickerDialog(
      asyncItems: getAsyncItems,
      initialSelectedItems: ['三'],
      itemBuilder: (context, value, index) => Padding(
        padding: const EdgeInsets.all(8.0),
        child: Text(value),
      ),
      title: '请选择多个值',
      dialogButton: DialogButton(
        context: context,
        positiveButtonName: '选择',
        negativeButtonName: '取消',
      ),
    );

    List<String> items = await dialog.show(context) ?? [];

    if (context.mounted) {
      SnackBar snackBar = SnackBar(
        content: Center(
          child: Text(items.isNotEmpty
              ? "'${items.join(', ')}' 被选择"
              : "未选择任何值"),
        ),
        behavior: SnackBarBehavior.floating,
      );

      ScaffoldMessenger.of(context)
        ..clearSnackBars()
        ..showSnackBar(snackBar);
    }
  }
}

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

1 回复

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


当然,以下是一个关于如何使用 versatile_dialogs 插件在 Flutter 中创建多功能对话框的代码案例。versatile_dialogs 是一个强大的 Flutter 插件,它提供了多种对话框样式和功能,以满足不同的需求。

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

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

然后,运行 flutter pub get 以获取依赖。

以下是一个简单的 Flutter 应用示例,展示了如何使用 versatile_dialogs 插件创建不同类型的对话框:

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

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

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

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

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Versatile Dialogs Example'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            ElevatedButton(
              onPressed: () => showAlertDialog(context),
              child: Text('Show Alert Dialog'),
            ),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: () => showConfirmationDialog(context),
              child: Text('Show Confirmation Dialog'),
            ),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: () => showInputDialog(context),
              child: Text('Show Input Dialog'),
            ),
          ],
        ),
      ),
    );
  }

  void showAlertDialog(BuildContext context) {
    VersatileDialog.alert(
      context: context,
      title: 'Alert Dialog',
      description: 'This is an alert dialog.',
      confirm: 'OK',
      onConfirm: () {
        // 用户点击确认按钮后的操作
        print('Alert Dialog confirmed');
      },
    );
  }

  void showConfirmationDialog(BuildContext context) {
    VersatileDialog.confirm(
      context: context,
      title: 'Confirmation Dialog',
      description: 'Are you sure you want to proceed?',
      confirm: 'Yes',
      cancel: 'No',
      onConfirm: () {
        // 用户点击确认按钮后的操作
        print('Confirmation Dialog confirmed');
      },
      onCancel: () {
        // 用户点击取消按钮后的操作
        print('Confirmation Dialog cancelled');
      },
    );
  }

  void showInputDialog(BuildContext context) {
    VersatileDialog.prompt(
      context: context,
      title: 'Input Dialog',
      description: 'Please enter your name:',
      initialValue: '',
      confirm: 'OK',
      cancel: 'Cancel',
      onConfirm: (String value) {
        // 用户点击确认按钮并输入值后的操作
        print('Input Dialog confirmed with value: $value');
      },
      onCancel: () {
        // 用户点击取消按钮后的操作
        print('Input Dialog cancelled');
      },
    );
  }
}

在这个示例中,我们创建了一个简单的 Flutter 应用,其中包含了三个按钮,分别用于显示不同类型的对话框:

  1. Alert Dialog:显示一个简单的警告对话框。
  2. Confirmation Dialog:显示一个带有确认和取消选项的对话框。
  3. Input Dialog:显示一个带有文本输入框的对话框。

每个对话框都使用了 VersatileDialog 提供的静态方法来创建和显示。你可以根据需要自定义对话框的标题、描述、按钮文本以及用户交互后的回调函数。

回到顶部