Flutter自定义弹窗Dialog效果

本文实例为大家分享了Flutter自定义弹窗Dialog效果的具体代码,供大家参考,具体内容如下

主要是基于系统的dialog机制做一些使用限制和自定义UI的优化

核心代码:

class CustomDialog {
 
  static void show(BuildContext context, Widget Function(BuildContext ctx, void Function() dismiss)builder, {bool cancellable = false}) {
    showDialog(
      context: context,
      barrierDismissible: cancellable,
      builder: (ctx) {
        return WillPopScope(
          child: Dialog(
            child: builder(ctx, () => Navigator.of(ctx).pop()),
            backgroundColor: Colors.transparent,
            shape: const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(0.0))),
            elevation: 0,
            alignment: Alignment.center,
          ),
          onWillPop: () async => cancellable,
        );
      },
    );
  }
 
 
  static void showBottomSheet(BuildContext context, Widget Function(BuildContext ctx, void Function() dismiss)builder, {bool cancellable = true}) {
 
    showModalBottomSheet(
      context: context,
      isDismissible: cancellable,
      enableDrag: cancellable,
      isScrollControlled: true,
      builder: (BuildContext ctx) {
        return WillPopScope(
          child: builder(ctx, () => Navigator.of(ctx).pop()),
          onWillPop: () async => cancellable,
        );
      },
      //不设置会默认使用屏幕最大宽度而不是子组件宽度
      constraints: const BoxConstraints(minWidth: 0, minHeight: 0, maxWidth: double.infinity, maxHeight: double.infinity),
      backgroundColor: Colors.transparent,
    );
  }
}

使用:

import 'dart:async';
import 'package:flutter/material.dart';
 
class DialogTestPage extends StatefulWidget {
  const DialogTestPage({Key? key}) : super(key: key);
 
  @override
  State<StatefulWidget> createState() => _DialogTestState();
}
 
class _DialogTestState extends State<DialogTestPage> {
  @override
  Widget build(BuildContext context) {
 
    return Scaffold(
      body: Column(children: [
        const SizedBox(height: 0, width: double.infinity,),
        TextButton(
          child: const Text("show dialog"),
          onPressed: () => showCustomDialog(),
        ),
        TextButton(
          child: const Text("show delay dialog"),
          onPressed: () => showDelayDialog(),
        ),
        TextButton(
          child: const Text("show sheet"),
          onPressed: () => showSheetDialog(),
        ),
      ], mainAxisAlignment: MainAxisAlignment.spaceAround, crossAxisAlignment: CrossAxisAlignment.center,),
    );
  }
 
 
  void showCustomDialog() {
    CustomDialog.show(context, (context, dismiss) {
      return Container(
        width: 200,
        height: 100,
        color: Colors.white,
        child: Center(child: TextButton(onPressed: () => dismiss(), child: const Text("POP")),),
      );
    });
  }
 
  void showSheetDialog() {
    CustomDialog.showBottomSheet(context, (ctx, dismiss) {
      return Container(
        height: 300,
        color: Colors.white,
        child: Center(child: TextButton(onPressed: () => dismiss(), child: const Text("POP")),),
        margin: const EdgeInsets.all(20),
      );
    });
  }
 
  void showDelayDialog() {
    CustomDialog.show(context, (context, dismiss) {
      //延时关闭
      Timer(const Duration(seconds: 2), () => dismiss());
 
      return Container(
        width: 200,
        height: 100,
        color: Colors.yellow,
        child: const Center(child: Text("等待"),),
      );
    }, cancellable: true);
  }
}

其中show方法中使用到的Dialog默认使用material组件库的,如果觉得有不合理的尺寸约束,可替换我修改过的Dialog组件,有其他需求也可在此定制,为什么不直接放弃使用此组件?主要涉及到其路由跳转中的一些动画布局之类的。

class Dialog extends StatelessWidget {
 
  const Dialog({
    Key? key,
    this.backgroundColor,
    this.elevation,
    this.insetAnimationDuration = const Duration(milliseconds: 100),
    this.insetAnimationCurve = Curves.decelerate,
    this.insetPadding = const EdgeInsets.symmetric(horizontal: 40.0, vertical: 24.0),
    this.clipBehavior = Clip.none,
    this.shape,
    this.alignment,
    this.child,
  }) : super(key: key);
 
 
  final Color? backgroundColor;
  final double? elevation;
  final Duration insetAnimationDuration;
  final Curve insetAnimationCurve;
  final EdgeInsets? insetPadding;
  final Clip clipBehavior;
  final ShapeBorder? shape;
  final AlignmentGeometry? alignment;
  final Widget? child;
 
  static const RoundedRectangleBorder _defaultDialogShape =
  RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(4.0)));
  static const double _defaultElevation = 24.0;
 
  @override
  Widget build(BuildContext context) {
    final DialogTheme dialogTheme = DialogTheme.of(context);
    final EdgeInsets effectivePadding = MediaQuery.of(context).viewInsets + (insetPadding ?? EdgeInsets.zero);
    return AnimatedPadding(
      padding: effectivePadding,
      duration: insetAnimationDuration,
      curve: insetAnimationCurve,
      child: MediaQuery.removeViewInsets(
        removeLeft: true,
        removeTop: true,
        removeRight: true,
        removeBottom: true,
        context: context,
        child: Align(
          alignment: alignment ?? dialogTheme.alignment ?? Alignment.center,
          child: Material(
            color: backgroundColor ?? dialogTheme.backgroundColor ?? Theme.of(context).dialogBackgroundColor,
            elevation: elevation ?? dialogTheme.elevation ?? _defaultElevation,
            shape: shape ?? dialogTheme.shape ?? _defaultDialogShape,
            type: MaterialType.card,
            clipBehavior: clipBehavior,
            child: child,
          ),
        ),
      ),
    );
  }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Flutter之自定义Dialog实现版本更新弹窗功能的实现

    功能点: 1.更新弹窗UI 2.强更与非强更且别控制 3.屏蔽物理返回键(因为强更的时候点击返回键,弹窗会消失) 4.点击弹窗外透明区域时,弹窗不消失 先看下效果图: Dialog实现代码: import 'package:flutter/material.dart'; import 'package:xiaopijiang/utils/assets_util.dart'; import 'package:xiaopijiang/utils/toast_util.dart'; ///create

  • Flutter 底部弹窗如何实现多项选择

    多选和单选的不同之处 单选的时候,选中一个就可以直接把结果返回,因此本身底部弹窗无需状态管理.但到多选的时候,需要知道当前选中的选项,有选项被点击的时候需要存储下来,当再次被点击的时候要清空这个选项,同时界面还需要同步更新,因此就涉及到状态管理了. 实现方式 在Flutter 中提供了一个 StatefulBuilder 的类,提供了一个 builder方法构建有状态组件,并且提供了状态更新方法,因此在里面完成状态管理. StatefulBuilder(builder: (context1, s

  • flutter实现更新弹窗内容例子(亲测有效)

    什么是Flutter Flutter 是谷歌推出的开发移动UI框架,可以快速的在IOS和Android上构建高质量的原生用户界面. Flutter可以与现有的代码一起工作,并且Flutter是完全免费的,开源的. 总结来说: Flutter是一款移动应用程序SDK,包含框架.widget和工具,为开发人员提供了一种在Android和iOS上构建和部署精美移动应用程序的简单高效的方式. Flutter的优势 快速开发 毫秒级的热重载,修改后,您的应用界面会立即更新.使用丰富的.完全可定制的widg

  • Flutter 底部弹窗ModelBottomSheet的使用示例

    实现效果 最终实现效果如图片所示,分布演示了基础的,全屏的和自定义的底部弹窗形式. 代码结构 在消息页面 message.dart 中,使用 Column 组件构建了三个按钮,点击每个按钮调用不同的底部弹窗显示.这部分代码不展示,核心注意的方式是按钮的 onPressed 响应方法,需要使用 async 修饰,这是因为 ModalBottomSheet 的返回结果是一个 Future 对象,需要通过 await 来获取返回结果. onPressed: () async { int selecte

  • Flutter实现底部弹窗效果

    目录 实现效果 代码结构 基本使用 自定义底部弹窗 总结 在实际开发过程中,经常会用到底部弹窗来进行快捷操作,例如选择一个选项,选择下一步操作等等.在 Flutter 中提供了一个 showModelBottomSheet 方法用于弹出底部弹窗,本篇介绍如何使用底部弹窗. 实现效果 最终实现效果如图片所示,分布演示了基础的,全屏的和自定义的底部弹窗形式. 代码结构 在消息页面 message.dart 中,使用 Column 组件构建了三个按钮,点击每个按钮调用不同的底部弹窗显示.这部分代码不展

  • Flutter多项选择弹窗实现详解

    目录 多选和单选的不同之处 实现方式 界面变更 代码实现 总结 在Flutter 底部弹窗详解一篇中介绍了底部弹窗的实现.发出后有在琢磨如何实现多选,这也是很常用的一个功能.本篇介绍实现多选的思路和实现方式. 多选和单选的不同之处 单选的时候,选中一个就可以直接把结果返回,因此本身底部弹窗无需状态管理.但到多选的时候,需要知道当前选中的选项,有选项被点击的时候需要存储下来,当再次被点击的时候要清空这个选项,同时界面还需要同步更新,因此就涉及到状态管理了. 实现方式 在Flutter 中提供了一个

  • Flutter自定义弹窗Dialog效果

    本文实例为大家分享了Flutter自定义弹窗Dialog效果的具体代码,供大家参考,具体内容如下 主要是基于系统的dialog机制做一些使用限制和自定义UI的优化 核心代码: class CustomDialog {     static void show(BuildContext context, Widget Function(BuildContext ctx, void Function() dismiss)builder, {bool cancellable = false}) {  

  • 支付宝小程序自定义弹窗dialog插件的实现代码

    支付宝小程序官方提供的alert提示框.dialog对话框.model弹窗功能比较有限,有些都不能随意自定义修改的.如是自己就捯饬着封装了个支付宝小程序自定义弹窗插件wcPop,多种展示场景,随意修改调用. 自定义的小程序弹窗采用了全新的模板布局,极简的api调用方式,同时解决了自定义弹窗出现时,蒙层下的页面仍可以滚动的问题. 在原始功能的基础上,新增了跟随定位弹窗.上下左右弹窗.弹窗swipe滑动功能 先来展示部分弹窗demo图: 在需要调用弹窗插件的页面引入tpl.js //信息框 btnT

  • Flutter自定义搜索框效果

    本文实例为大家分享了Flutter自定义搜索框效果的具体代码,供大家参考,具体内容如下 效果 实现方式 import 'package:dio/dio.dart'; import 'package:flutter/material.dart'; import 'package:keduo/base/baseSize.dart'; import 'package:keduo/utils/icon_utils.dart'; class SearchBarWidget extends Stateful

  • Android自定义弹窗提示效果

    本文实例为大家分享了Android 自定义弹窗提示的具体代码,供大家参考,具体内容如下 Java文件: private void showSetDeBugDialog() { AlertDialog.Builder setDeBugDialog = new AlertDialog.Builder(this); //获取界面 View dialogView = LayoutInflater.from(this).inflate(R.layout.system_admin_psw_alert_dia

  • Android自定义带增长动画和点击弹窗提示效果的柱状图DEMO

    项目中最近用到各种图表,本来打算用第三方的,例如MPAndroid,这是一个十分强大的图表库,应用起来十分方便,但是最终发现和设计不太一样,没办法,只能自己写了.今天将写好的柱状图的demo贴在这,该柱状图可根据数据的功能有一下几点: 1. 根据数据的多少,动态的绘制柱状图柱子的条数: 2. 柱状图每条柱子的绘制都有动态的动画效果: 3. 每条柱子有点击事件,点击时弹出提示框,显示相关信息,规定时间后,弹窗自动消失. 好了,先上演示图: 下边贴出相关代码: 自定义柱状图类: package co

  • Flutter自定义Appbar搜索框效果

    本文实例为大家分享了Flutter自定义Appbar搜索框效果的具体代码,供大家参考,具体内容如下 首先看一下实现本次实现的效果. 本来想直接偷懒从flutter pub上找个能用的使用起来,但是看了下发现都与目前ui效果相差很大,于是乎决定自己实现一个.整体的话比较简单,本来也是为了练手而做的. 为了方便处理statusbar的高度适配,于是乎直接依托于Appbar进行了实现,这样就可以不用处理状态栏适配了. class _HotWidgetState extends State<HotWid

  • Android自定义弹框Dialog效果

    本文实例为大家分享了Android自定义弹框Dialog效果的具体代码,供大家参考,具体内容如下 1.dialog_delete.xml <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"     android:layout_width="ma

  • 微信小程序自定义弹窗滚动与页面滚动冲突的解决方法

    本文为大家分享了微信小程序自定义弹窗滚动与页面滚动冲突的解决方法,供大家参考,具体内容如下 先看效果是否是自己需要的 实现步骤: 1.整个布局用作为根节点包裹所有view,并动态绑定scroll-view的scroll-y属性 2.样式文件中设置Page的overflow-y属性值为hidden 3.样式文件中设置scroll-view的height属性值为100% 4.打开自定义弹窗的点击事件中,更改isScroll的值为false,关闭弹窗的点击事件中,更改isScroll的值为true J

  • 微信小程序实现自定义弹窗组件的示例代码

    目录 编写组件代码 Dialog.wxml Dialog.js Dialog.wxss 调用自定义组件 上一篇中说的是小程序自带的弹窗组件,今天,我们来试试小程序的自定义组件,我们自定义一个带确定取消的弹窗组件. 首先,放一下,最终的效果图: 这是我们最后要实现的效果 那么,首先,我们创建一个组件 新建component文件夹存放我们的组件,里边存放的就是我们所用的组件,我们今天要做的事弹出框,新建文件夹popup存放我们的组件模板,点击右键选择新建component,就会自动生成组件的模板wx

随机推荐