Flutter:全屏半透明模态对话框

这篇实用的文章向你展示了如何在 Flutter 中实现一个全屏半透明模态对话框(带有一些动画)。

快速概览

为了制作上述对话框,我们创建了一个名为 FullScreenModal 的类(名称完全由您决定),它扩展了内置的ModalRoute类,如下所示:

lass FullScreenModal extends ModalRoute {
  @override
  Duration get transitionDuration => const Duration(milliseconds: 500);

  @override
  bool get opaque => false;

  @override
  bool get barrierDismissible => false;

  @override
  Color get barrierColor => Colors.black.withOpacity(0.6);

  @override
  String? get barrierLabel => null;

  @override
  bool get maintainState => true;

  @override
  Widget buildPage(
    BuildContext context,
    Animation<double> animation,
    Animation<double> secondaryAnimation,
  ) {
    return Material(
      type: MaterialType.transparency,
      child: Center(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            const Text(
              'This is a title',
              style: TextStyle(color: Colors.white, fontSize: 40.0),
            ),
            const SizedBox(
              height: 15,
            ),
            const Text('Just some dummy description text',
                style: TextStyle(color: Colors.white, fontSize: 18)),
            const SizedBox(
              height: 30,
            ),
            ElevatedButton.icon(
              onPressed: () => Navigator.pop(context),
              icon: const Icon(Icons.close),
              label: const Text('Close'),
            )
          ],
        ),
      ),
    );
  }

  @override
  Widget buildTransitions(BuildContext context, Animation<double> animation,
      Animation<double> secondaryAnimation, Widget child) {
    // add fade animation
    return FadeTransition(
      opacity: animation,
      // add slide animation
      child: SlideTransition(
        position: Tween<Offset>(
          begin: const Offset(0, -1),
          end: Offset.zero,
        ).animate(animation),
        // add scale animation
        child: ScaleTransition(
          scale: animation,
          child: child,
        ),
      ),
    );
  }
}

要查看完整的源代码,请转到下一部分。

完整示例

应用预览

我们要制作的小应用程序有一个浮动操作按钮。按下此按钮时,将显示全屏模式。此模式对话框具有透明的黑色背景。当它出现时,其内容将有以下动作:

  • 淡出动画
  • 幻灯片动画(自上而下的过渡)
  • 缩放动画(大小从小到大增加)

在模态框内,有一个关闭按钮可以用来关闭它。

以下是它的工作原理:

Flutter:全屏半透明模态对话框

代码

main.dart中的完整源代码及说明:

// KindaCode.com
// main.dart
import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      // remove the debug banner
      debugShowCheckedModeBanner: false,
      title: 'KindaCode.com',
      theme: ThemeData(
        primarySwatch: Colors.amber,
      ),
      home: const HomeScreen(),
    );
  }
}

// this class defines the full-screen semi-transparent modal dialog
// by extending the ModalRoute class
class FullScreenModal extends ModalRoute {
  @override
  Duration get transitionDuration => const Duration(milliseconds: 500);

  @override
  bool get opaque => false;

  @override
  bool get barrierDismissible => false;

  @override
  Color get barrierColor => Colors.black.withOpacity(0.6);

  @override
  String? get barrierLabel => null;

  @override
  bool get maintainState => true;

  @override
  Widget buildPage(
    BuildContext context,
    Animation<double> animation,
    Animation<double> secondaryAnimation,
  ) {
    return Material(
      type: MaterialType.transparency,
      child: Center(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            const Text(
              'This is a title',
              style: TextStyle(color: Colors.white, fontSize: 40.0),
            ),
            const SizedBox(
              height: 15,
            ),
            const Text('Just some dummy description text',
                style: TextStyle(color: Colors.white, fontSize: 18)),
            const SizedBox(
              height: 30,
            ),
            ElevatedButton.icon(
              onPressed: () => Navigator.pop(context),
              icon: const Icon(Icons.close),
              label: const Text('Close'),
            )
          ],
        ),
      ),
    );
  }

  @override
  Widget buildTransitions(BuildContext context, Animation<double> animation,
      Animation<double> secondaryAnimation, Widget child) {
    // add fade animation
    return FadeTransition(
      opacity: animation,
      // add slide animation
      child: SlideTransition(
        position: Tween<Offset>(
          begin: const Offset(0, -1),
          end: Offset.zero,
        ).animate(animation),
        // add scale animation
        child: ScaleTransition(
          scale: animation,
          child: child,
        ),
      ),
    );
  }
}

// This is the main screen of the application
class HomeScreen extends StatelessWidget {
  const HomeScreen({Key? key}) : super(key: key);

  void _showModal(BuildContext context) {
    Navigator.of(context).push(FullScreenModal());
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('KindaCode.com')),
      body: Container(),
      // this button is used to show the modal
      floatingActionButton: FloatingActionButton.extended(
        onPressed: () => _showModal(context),
        label: const Text('Show Modal'),
        icon: const Icon(Icons.play_arrow),
      ),
    );
  }
}

结语

我们已经研究了在 Flutter 中从头开始构建全屏半透明对话框的端到端示例。尝试修改代码,添加一些东西,删除一些东西,更改一些值,看看接下来会发生什么。

免责声明:
1.本站所有内容由本站原创、网络转载、消息撰写、网友投稿等几部分组成。
2.本站原创文字内容若未经特别声明,则遵循协议CC3.0共享协议,转载请务必注明原文链接。
3.本站部分来源于网络转载的文章信息是出于传递更多信息之目的,不意味着赞同其观点。
4.本站所有源码与软件均为原作者提供,仅供学习和研究使用。
5.如您对本网站的相关版权有任何异议,或者认为侵犯了您的合法权益,请及时通知我们处理。
火焰兔 » Flutter:全屏半透明模态对话框