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的嵌套和各种默认值,做一些大小动态调整的组件还是需要一些工作量,要注意一些坑。


目录
相关文章
|
13天前
|
UED 开发者 容器
Flutter&鸿蒙next 的 Sliver 实现自定义滚动效果
Flutter 提供了强大的滚动组件,如 ListView 和 GridView,但当需要更复杂的滚动效果时,Sliver 组件是一个强大的工具。本文介绍了如何使用 Sliver 实现自定义滚动效果,包括 SliverAppBar、SliverList 等常用组件的使用方法,以及通过 CustomScrollView 组合多个 Sliver 组件实现复杂布局的示例。通过具体代码示例,展示了如何实现带有可伸缩 AppBar 和可滚动列表的页面。
74 1
|
15天前
Flutter 自定义组件继承与调用的高级使用方式
本文深入探讨了 Flutter 中自定义组件的高级使用方式,包括创建基本自定义组件、继承现有组件、使用 Mixins 和组合模式等。通过这些方法,您可以构建灵活、可重用且易于维护的 UI 组件,从而提升开发效率和代码质量。
111 1
|
15天前
|
前端开发 开发者
深入探索 Flutter 鸿蒙版的画笔使用与高级自定义动画
本文深入探讨了 Flutter 中的绘图功能,重点介绍了 CustomPainter 和 Canvas 的使用方法。通过示例代码,详细讲解了如何绘制自定义图形、设置 Paint 对象的属性以及实现高级自定义动画。内容涵盖基本绘图、动画基础、渐变动画和路径动画,帮助读者掌握 Flutter 绘图与动画的核心技巧。
64 1
|
15天前
|
Dart UED 开发者
Flutter&鸿蒙next中的按钮封装:自定义样式与交互
在Flutter应用开发中,按钮是用户界面的重要组成部分。Flutter提供了多种内置按钮组件,但有时这些样式无法满足特定设计需求。因此,封装一个自定义按钮组件变得尤为重要。自定义按钮组件可以确保应用中所有按钮的一致性、可维护性和可扩展性,同时提供更高的灵活性,支持自定义颜色、形状和点击事件。本文介绍了如何创建一个名为CustomButton的自定义按钮组件,并详细说明了其样式、形状、颜色和点击事件的处理方法。
64 1
|
15天前
|
Dart 搜索推荐 API
Flutter & 鸿蒙next版本:自定义对话框与表单验证的动态反馈与错误处理
在现代移动应用开发中,用户体验至关重要。本文探讨了如何在 Flutter 与鸿蒙操作系统(HarmonyOS)中创建自定义对话框,并结合表单验证实现动态反馈与错误处理,提升用户体验。通过自定义对话框和表单验证,开发者可以提供更加丰富和友好的交互体验,同时利用鸿蒙next版本拓展应用的受众范围。
65 1
|
1月前
|
开发者 UED
flutter:dialog (十一)
本文介绍了 Flutter 中常用的弹窗组件和方法,包括 `AlertDialog`、`SimpleDialog`、`showModalBottomSheet` 和 `toast`。每个组件的使用方法和示例代码都进行了详细说明,帮助开发者快速理解和应用这些弹窗功能。例如,`AlertDialog` 用于显示带有标题、内容和按钮的对话框;`SimpleDialog` 用于显示多个选项供用户选择;`showModalBottomSheet` 用于从屏幕底部弹出模态对话框;而 `toast` 则用于显示短暂的消息提示。文中还提供了如何处理点击事件、取消弹窗等常见操作的代码示例。
|
1月前
|
开发框架 移动开发 Android开发
安卓与iOS开发中的跨平台解决方案:Flutter入门
【9月更文挑战第30天】在移动应用开发的广阔舞台上,安卓和iOS两大操作系统各自占据半壁江山。开发者们常常面临着选择:是专注于单一平台深耕细作,还是寻找一种能够横跨两大系统的开发方案?Flutter,作为一种新兴的跨平台UI工具包,正以其现代、响应式的特点赢得开发者的青睐。本文将带你一探究竟,从Flutter的基础概念到实战应用,深入浅出地介绍这一技术的魅力所在。
74 7
|
2月前
|
前端开发 搜索推荐
Flutter中自定义气泡框效果的实现
Flutter中自定义气泡框效果的实现
82 3
|
3月前
|
Dart 前端开发 JavaScript
Flutter&Dart-异步编程Future、Stream极速入门
Flutter&Dart-异步编程Future、Stream极速入门
72 4
Flutter&Dart-异步编程Future、Stream极速入门
|
3月前
|
前端开发
Flutter快速实现自定义折线图,支持数据改变过渡动画
Flutter快速实现自定义折线图,支持数据改变过渡动画
91 4
Flutter快速实现自定义折线图,支持数据改变过渡动画