这段代码是一个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!);
}
}
以下是代码分析内容:
-
整体功能概述
这段 Flutter 代码创建了一个应用程序,其主要功能是在主屏幕呈现一个按钮,点击该按钮会弹出一个自定义模态对话框。用户可在对话框中输入内容,点击 “确认” 按钮后,输入内容会显示在主屏幕按钮下方;点击 “取消” 按钮则关闭对话框且无其他操作。 -
代码结构分析
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,用于存储用户在模态对话框中输入的内容。
- 界面构建与交互逻辑
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 机制实现模态对话框显示和交互逻辑的相关操作。不过在实际应用中,可能需对一些细节进行优化,比如对话框在不同屏幕尺寸下的定位适配、点击对话框外部区域关闭对话框的更完善逻辑等。