flutter的overlay组件示例5

这段代码是一个Flutter应用程序,用于展示如何使用覆盖式模态对话框。

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Overlay Modal Dialog Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: HomeScreen(),
    );
  }
}

class HomeScreen extends StatefulWidget {
  
  _HomeScreenState createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  String? userInput; // Store the user input

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Overlay Modal Dialog Example'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            ElevatedButton(
              onPressed: () {
                _showCustomDialog(context);
              },
              child: Text('打开模态对话框'),
            ),
            SizedBox(height: 20),
            // Display the user input after confirmation
            if (userInput != null) Text('用户输入: $userInput'),
          ],
        ),
      ),
    );
  }

  void _showCustomDialog(BuildContext context) {
    OverlayEntry? overlayEntry;
    TextEditingController textController =
        TextEditingController(); // Create a TextEditingController

    void removeOverlayEntry() {
      if (overlayEntry != null) {
        overlayEntry!.remove();
        overlayEntry = null;
      }
    }

    overlayEntry = OverlayEntry(
      builder: (context) => Positioned(
        top: MediaQuery.of(context).size.height * 0.3,
        left: MediaQuery.of(context).size.width * 0.1,
        right: MediaQuery.of(context).size.width * 0.1,
        child: Material(
          color: Colors.transparent,
          child: Container(
            padding: EdgeInsets.all(20),
            decoration: BoxDecoration(
              color: Colors.white,
              borderRadius: BorderRadius.circular(10),
              boxShadow: [BoxShadow(blurRadius: 10, color: Colors.black26)],
            ),
            child: GestureDetector(
              onTap: () {
                // Prevent clicks outside the dialog from closing it
              },
              child: Column(
                mainAxisSize: MainAxisSize.min,
                children: [
                  Text(
                    '确认操作',
                    style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
                  ),
                  SizedBox(height: 20),
                  Text('您确定要执行此操作吗?'),
                  SizedBox(height: 20),
                  // Add a TextField for user input
                  TextField(
                    controller: textController,
                    decoration: InputDecoration(
                      labelText: '输入内容',
                      border: OutlineInputBorder(),
                    ),
                  ),
                  SizedBox(height: 20),
                  Row(
                    mainAxisAlignment: MainAxisAlignment.end,
                    children: [
                      TextButton(
                        onPressed: () {
                          // Get the input value and update the state
                          setState(() {
                            userInput =
                                textController.text; // Get the input value
                          });
                          removeOverlayEntry(); // Close the dialog
                        },
                        child: Text('确认'),
                      ),
                      SizedBox(width: 10),
                      TextButton(
                        onPressed: () {
                          removeOverlayEntry(); // Close the dialog
                        },
                        child: Text('取消'),
                      ),
                    ],
                  ),
                ],
              ),
            ),
          ),
        ),
      ),
    );

    Overlay.of(context)?.insert(overlayEntry!);
  }
}

以下是代码分析内容:

  1. 整体功能概述
    这段 Flutter 代码创建了一个应用程序,其主要功能是在主屏幕呈现一个按钮,点击该按钮会弹出一个自定义模态对话框。用户可在对话框中输入内容,点击 “确认” 按钮后,输入内容会显示在主屏幕按钮下方;点击 “取消” 按钮则关闭对话框且无其他操作。

  2. 代码结构分析
    2.1 入口点 main 函数
    首先导入了 flutter/material.dart 库,它是 Flutter 应用开发用于构建用户界面的常用 UI 库,涵盖各种组件及样式相关类等。
    main 函数作为 Flutter 应用的入口点,通过调用 runApp 函数并传入 MyApp 类的实例来启动应用程序。

2.2 MyApp 类
MyApp 类继承自 StatelessWidget,属于无状态组件,创建后其外观和行为通常不会改变(除非父组件重新构建它)。
在其 build 方法中,返回 MaterialApp 实例,用于配置应用的基本属性,如设置标题为 ‘Overlay Modal Dialog Example’,指定主题主色调为蓝色(通过 primarySwatch: Colors.blue),并将应用首页设为 HomeScreen 类的实例。

2.3 HomeScreen 类及其状态类 _HomeScreenState
HomeScreen 类继承自 StatefulWidget,是有状态组件,内部状态在应用运行中可能改变,通过重写 createState 方法创建对应的状态类 _HomeScreenState 实例。
在 _HomeScreenState 类中定义了一个可空字符串变量 userInput,用于存储用户在模态对话框中输入的内容。

  1. 界面构建与交互逻辑
    3.1 _HomeScreenState 的 build 方法
    构建了包含 Scaffold 的界面,Scaffold 是 Flutter 常用布局组件,提供应用栏、主体内容等布局区域。
    在 Scaffold 的 appBar 部分设置标题为 ‘Overlay Modal Dialog Example’。
    body 部分通过 Center 组件将子组件居中显示,该子组件是一个 Column,其主轴方向对齐方式为居中。Column 中有两个主要部分:
    一个 ElevatedButton,点击时调用 _showCustomDialog 方法以显示模态对话框,按钮显示文本为 “打开模态对话框”。
    若 userInput 不为空(即用户已在对话框输入并确认),则显示一个 Text 组件展示用户输入内容,格式为 “用户输入: [具体输入内容]”。

3.2 _ShowCustomDialog 方法
该方法用于显示自定义模态对话框。首先定义可空的 OverlayEntry 变量 overlayEntry 和 TextEditingController 实例 textController,后者用于控制 TextField 的文本输入操作。
定义内部函数 removeOverlayEntry,用于移除已创建的 OverlayEntry(即关闭对话框),通过判断 overlayEntry 是否为空,不为空则调用其 remove 方法并将其置为 null。
创建 OverlayEntry 实例,通过其 builder 回调函数构建对话框具体内容:
用 Positioned 组件定位对话框在屏幕上的位置,设置了相对屏幕顶部、左右两侧的距离比例。
对话框主体是 Material 组件,颜色设为透明,内部包含 Container 组件,该组件设置了白色背景、圆角边框及阴影效果等装饰属性。
在 Container 内部有 GestureDetector,用于处理点击事件,虽通过空的 onTap 回调函数防止点击对话框外部区域关闭对话框,但实际可能需完善此逻辑。
GestureDetector 的子组件是 Column,包含以下内容:
显示 “确认操作” 的 Text 组件,设置了较大字体和加粗样式。
提示性的 Text 组件,如 “您确定要执行此操作吗?”。
一个 TextField 组件,由 textController 控制输入操作,设置了输入框标签及边框样式等装饰。
一个 Row 组件,放置两个 TextButton:
点击 “确认” 按钮时,先通过 setState 方法更新 userInput 变量的值为 textController 文本的值,再调用 removeOverlayEntry 函数关闭对话框,使输入内容显示在主屏幕上。
点击 “取消” 按钮时,直接调用 removeOverlayEntry 函数关闭对话框,不做其他操作。
最后,通过 Overlay.of(context)?.insert(overlayEntry!) 将创建好的 OverlayEntry 插入到 Overlay 层中,显示出模态对话框。

总体而言,这段代码实现了一个带有输入功能的基本模态对话框示例,展示了 Flutter 中界面构建、用户输入处理以及通过 Overlay 机制实现模态对话框显示和交互逻辑的相关操作。不过在实际应用中,可能需对一些细节进行优化,比如对话框在不同屏幕尺寸下的定位适配、点击对话框外部区域关闭对话框的更完善逻辑等。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值