Flutter入门:自定义dialog

简介: 自定义dialog

自定义dialog


先来看看一个示例


class ExamResultDialog extends Dialog{
  ...
  @override
  Widget build(BuildContext context) {
    return new ExamResultDialogContent(entity, listener);
  }
}
class ExamResultDialogContent extends StatefulWidget{
  ...
  @override
  State<StatefulWidget> createState() {
    ...
    return _ExamResultDialogContent();
  }
  ...
}
class _ExamResultDialogContent extends State<ExamResultDialogContent>{
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.transparent,
      body: Center(
        child: Container(
          decoration: BoxDecoration(
            color: Colors.white,
            borderRadius: BorderRadius.all(Radius.circular(20)),
          ),
          width: 752,
          height: 426,
          child: ...,   //内容部分
        ),
      ),
    );
  }
}
复制代码


从上面可以看到先继承dialog,在它的build函数然后widget,剩下的与正常的widget差不多。

但是注意几点:

  • 最外层需要用Scaffold包裹,否则所有默认样式都会失效。
  • 使用Scaffold后,背景是不透明的,需要再设置backgroundColor为透明的。
  • dialog默认是全屏的,所以需要用Container来限制内容的大小,并用Center包裹使内容居中。同时也可以对Container添加decoration实现弹窗背景


大小动态调整的Dialog


开发中经常遇到这样的dialog,内容变化很大,所以dialog的大小也要跟着变化,但是为了美观又不能太大,当内容过多的时候dialog大小就不再改变,而是内容可滚动查看。

下面我们一步步实现这个dialog


Text内容可滚动


这里同时也解决Text显示不全的问题。

我们用最简单的dialog,内容只有文字,那么第一步要解决的就是如果文字特别多的情况下,怎么让Text的内容可以滚动。

答案是用SingleChildScrollView,它只有一个child,作用就是如果child太大的情况下可以滚动查看。

代码:

SingleChildScrollView(
   child: Text(
      widget.msg,
      style:TextStyle(color: Color(0xff919294), fontSize: 18),
),
复制代码


但是这里有一个问题,就是虽然能滚动了,但是Text显示不全,现象是当Text文字内容很多的时候,最后一行看不到,而倒数第二行只能显示一半。

这个不是SingleChildScrollView的问题,经测试,在空白页面上单独使用Text,高度不限,依然会出现这样的情况,甚至Text下半部分还空白着,后面的文字依然不显示。

注意:这个情况是发生在flutter web,在chrome上出现,在Android或ios未测试,可能是web特有的问题


经过反复尝试,最终发现为Text设置overflow: TextOverflow.ellipsis可以解决,文字可以完整显示出来了。

overflow的作用就是文字显示不下时采用什么样的处理,ellipsis就是省略,还有shape(渐变)、visible等等。这里不知道为什么设置ellipsis可以起作用,反而设置visible不行。


但是设置overflow: TextOverflow.ellipsis可以解决单独使用Text时的问题,如果使用SingleChildScrollView嵌套到达滚动效果的话,Text只显示一行。。。

这里我的解决方法时设置Text的maxLines: 100 这里的100只是一个较大的数,可以是1000,只有保证内容完全显示即可。


这个解决方案并不理想,但是暂时只想到这个解决方案。最终代码:

SingleChildScrollView(
   child: Text(
      widget.msg,
      overflow: TextOverflow.ellipsis,
      maxLines: 100,
      style:TextStyle(color: Color(0xff919294), fontSize: 18),
),
复制代码


窗口大小动态调整并限制最大高度


这里使用LimitedBox来实现高度的限制,直接上代码:

SizedBox(
    width: 400,
    child: Container(
      child: Stack(
        children: [
          Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              Container(
                child: Text(
                  "公告",
                  style: TextStyle(color: Color(0xff212223), fontSize: 24),
                ),
                width: double.infinity,
                alignment: Alignment.center,
                margin: EdgeInsets.only(top: 10, bottom: 20),
              ),
              LimitedBox(
                maxHeight: 400,
                child: SingleChildScrollView(
                  child: Text(
                    widget.msg,
                    overflow: TextOverflow.ellipsis,
                    maxLines: 100,
                    style:
                        TextStyle(color: Color(0xff919294), fontSize: 18),
                  ),
                  padding: EdgeInsets.only(left: 20, right: 20),
                ),
              ),
              Padding(padding: EdgeInsets.all(10))
            ],
          ),
          GestureDetector(
            child: Container(
              child: Image.asset(
                R.assetsAlertClose,
                width: 20,
                height: 20,
              ),
              padding: EdgeInsets.all(10),
              alignment: Alignment.topRight,
            ),
            onTap: () {
              Navigator.of(context).pop();
            },
          )
        ],
      ),
      decoration: ShapeDecoration(
        color: Colors.white,
        shape: RoundedRectangleBorder(
          side: BorderSide(color: Colors.transparent),
          borderRadius: BorderRadius.all(
            Radius.circular(13),
          ),
        ),
      ),
    ));
复制代码


最外层是一个SizedBox,目的是设置窗口的宽度,这个是固定的,而窗口的高度是动态的。 然后就遇到了第一个问题,一开始我在第二层就使用LimitedBox,如下:


SizedBox(
    width: 400,
    child: LimitedBox(
       maxHeight: 400,
    child: Container(
     ...
复制代码


但是这样无论Container内容有多大,Container高度(甚至里面没有任何内容)都一直是400,而我们期望的是Container高度可以随着内容变化,而最大高度限制在400

经过尝试,将LimitedBox放在Container里层即可,具体原因还不得而知,Flutter UI嵌套感觉问题一直很多。


最终结果就像上面一样,只在内容部分的外层套一层LimitedBox来限制最大高度,这样就实现了动态变化且有最大限制。

这里还要注意,在Column中我设置了mainAxisSize: MainAxisSize.min 因为默认Column是在垂直方向上是完全展开的,这样高度就不能动态变化了,所以这里的设置让Column垂直方向上根据内容展示即可。

在flutter中由于各种ui的嵌套和各种默认值,做一些大小动态调整的组件还是需要一些工作量,要注意一些坑。


目录
相关文章
|
1月前
|
Dart 前端开发 开发工具
【Flutter前端技术开发专栏】Flutter入门指南:搭建开发环境与第一个应用
【4月更文挑战第30天】本文介绍了Flutter SDK的安装和配置过程,以及如何创建并运行第一个Flutter应用。首先确保安装了Dart SDK和Flutter SDK,支持macOS、Linux和Windows。安装完成后,设置环境变量,然后通过`flutter doctor`验证安装。接着,使用`flutter create`命令创建新项目,进入项目目录并运行`flutter run`启动应用。在`main.dart`中修改代码以自定义应用。Flutter支持热重载和DevTools调试。本文为Flutter初学者提供了快速入门的指导。
【Flutter前端技术开发专栏】Flutter入门指南:搭建开发环境与第一个应用
|
9天前
Flutter自定义对话框返回相关问题汇总
Flutter自定义对话框返回相关问题汇总
8 0
|
9天前
|
API 容器
Flutter 自定义实现时间轴、侧边进度条
Flutter 自定义实现时间轴、侧边进度条
16 0
|
1月前
|
数据库 Android开发
Android数据库框架-GreenDao入门,2024年最新flutter 页面跳转动画
Android数据库框架-GreenDao入门,2024年最新flutter 页面跳转动画
Android数据库框架-GreenDao入门,2024年最新flutter 页面跳转动画
|
1月前
|
前端开发 搜索推荐 开发者
【Flutter前端技术开发专栏】Flutter中的自定义主题与暗黑模式
【4月更文挑战第30天】本文介绍了如何在Flutter中自定义主题和实现暗黑模式。通过`ThemeData`类定义应用的外观,包括颜色、字体和样式。示例展示了如何设置主色、强调色及文本、按钮主题。暗黑模式可通过`darkTheme`属性启用,结合`ThemeData.dark()`方法定制。利用`MediaQuery`监听系统亮度变化,动态调整暗黑模式状态。Flutter的这些特性有助于开发者创建独特且用户友好的界面。
【Flutter前端技术开发专栏】Flutter中的自定义主题与暗黑模式
|
1月前
|
缓存 前端开发 搜索推荐
【Flutter前端技术开发专栏】Flutter中的自定义绘制与Canvas API
【4月更文挑战第30天】Flutter允许开发者通过`CustomPaint`和`CustomPainter`进行自定义绘制,以实现丰富视觉效果。`CustomPaint` widget将`CustomPainter`应用到画布,而`CustomPainter`需实现`paint`和`shouldRepaint`方法。`paint`用于绘制图形,如示例中创建的`MyCirclePainter`绘制蓝色圆圈。Canvas API提供绘制形状、路径、文本和图片等功能。注意性能优化,避免不必要的重绘和利用缓存提升效率。自定义绘制让Flutter UI更具灵活性和个性化,但也需要图形学知识和性能意识。
【Flutter前端技术开发专栏】Flutter中的自定义绘制与Canvas API
|
1月前
|
开发框架 前端开发 搜索推荐
【Flutter前端技术开发专栏】Flutter中的自定义Widget与渲染流程
【4月更文挑战第30天】探索Flutter的自定义Widget与渲染流程。自定义Widget是实现复杂UI设计的关键,优点在于个性化设计、功能扩展和代码复用,但也面临性能优化和复杂性管理的挑战。创建步骤包括设计结构、定义Widget类、实现构建逻辑和处理交互。Flutter渲染流程涉及渲染对象树、布局、绘制和合成阶段。实践案例展示如何创建带渐变背景和阴影的自定义按钮。了解这些知识能提升应用体验并应对开发挑战。查阅官方文档以深入学习。
【Flutter前端技术开发专栏】Flutter中的自定义Widget与渲染流程
|
1月前
|
前端开发 开发者 UED
Flutter的自定义Painter:深入探索自定义绘制Widget的技术实现
【4月更文挑战第26天】Flutter的自定义Painter允许开发者根据需求绘制独特UI,通过继承`CustomPaint`类和重写`paint`方法实现。在`paint`中使用`Canvas`绘制图形、路径等。创建自定义Painter类后,将其作为`CustomPaint` Widget的`painter`属性使用。此技术可实现自定义形状、渐变、动画等复杂效果,提升应用视觉体验。随着Flutter的进化,自定义Painter将提供更丰富的功能。
|
1月前
|
运维 监控 定位技术
应用研发平台EMAS常见问题之flutter插件不支持自定义图标如何解决
应用研发平台EMAS(Enterprise Mobile Application Service)是阿里云提供的一个全栈移动应用开发平台,集成了应用开发、测试、部署、监控和运营服务;本合集旨在总结EMAS产品在应用开发和运维过程中的常见问题及解决方案,助力开发者和企业高效解决技术难题,加速移动应用的上线和稳定运行。
|
1月前
|
容器
Flutter 自定义实现时间轴、侧边进度条
时间轴和侧边进度条是非常常见的 UI 控件,它们可以增强应用的视觉效果和交互体验。在这篇文章中,我们将详细介绍如何使用 Flutter 自定义实现这两个控件。
152 1