网站首页 > 教程文章 正文
千里之行,始于足下,坚持不断地学习,才能创造更好的价值,今天继续学习flutter框架的用法,还是采用调试代码,给出具体原理,动手去做,永远比光看书要方便地多;
一 程序界面
二 代码
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'TextField & TextFormField 示例',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: const InputExampleScreen(),
);
}
}
class InputExampleScreen extends StatefulWidget {
const InputExampleScreen({super.key});
@override
State<InputExampleScreen> createState() => _InputExampleScreenState();
}
class _InputExampleScreenState extends State<InputExampleScreen> {
// 普通TextField的控制器
final TextEditingController _textFieldController = TextEditingController();
// 用于存储TextField的输入值
String _textFieldValue = '';
// 表单的全局键,用于表单验证和提交
final _formKey = GlobalKey<FormState>();
// 表单字段的控制器
final TextEditingController _nameController = TextEditingController();
final TextEditingController _emailController = TextEditingController();
final TextEditingController _passwordController = TextEditingController();
@override
void dispose() {
// 清理控制器资源
_textFieldController.dispose();
_nameController.dispose();
_emailController.dispose();
_passwordController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('TextField & TextFormField 示例'),
),
body: SingleChildScrollView(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// TextField部分
const Text(
'1. TextField 示例',
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
const SizedBox(height: 10),
TextField(
controller: _textFieldController,
decoration: const InputDecoration(
labelText: '输入一些文本',
hintText: '请输入...',
prefixIcon: Icon(Icons.text_fields),
border: OutlineInputBorder(),
),
keyboardType: TextInputType.text,
textInputAction: TextInputAction.done,
maxLength: 50,
obscureText: false,
onChanged: (value) {
// 实时监听输入变化
setState(() {
_textFieldValue = value;
});
},
onSubmitted: (value) {
// 当用户完成输入时触发
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('你输入了: $value')),
);
},
),
const SizedBox(height: 8),
Text('当前输入: $_textFieldValue'),
const SizedBox(height: 20),
ElevatedButton(
onPressed: () {
// 获取TextField的值
String value = _textFieldController.text;
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('通过控制器获取的值: $value')),
);
},
child: const Text('获取TextField的值'),
),
const SizedBox(height: 40),
// TextFormField部分
const Text(
'2. TextFormField 示例 (表单中)',
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
const SizedBox(height: 10),
Form(
key: _formKey,
child: Column(
children: [
TextFormField(
controller: _nameController,
decoration: const InputDecoration(
labelText: '姓名',
hintText: '请输入您的姓名',
prefixIcon: Icon(Icons.person),
border: OutlineInputBorder(),
),
// 验证逻辑
validator: (value) {
if (value == null || value.isEmpty) {
return '请输入姓名';
}
if (value.length < 2) {
return '姓名长度不能少于2个字符';
}
return null;
},
),
const SizedBox(height: 16),
TextFormField(
controller: _emailController,
decoration: const InputDecoration(
labelText: '邮箱',
hintText: '请输入您的邮箱',
prefixIcon: Icon(Icons.email),
border: OutlineInputBorder(),
),
keyboardType: TextInputType.emailAddress,
// 验证逻辑
validator: (value) {
if (value == null || value.isEmpty) {
return '请输入邮箱';
}
// 简单的邮箱格式验证
if (!RegExp(r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}#39;)
.hasMatch(value)) {
return '请输入有效的邮箱地址';
}
return null;
},
),
const SizedBox(height: 16),
TextFormField(
controller: _passwordController,
decoration: const InputDecoration(
labelText: '密码',
hintText: '请输入密码',
prefixIcon: Icon(Icons.lock),
border: OutlineInputBorder(),
),
obscureText: true, // 密码隐藏
// 验证逻辑
validator: (value) {
if (value == null || value.isEmpty) {
return '请输入密码';
}
if (value.length < 6) {
return '密码长度不能少于6个字符';
}
return null;
},
),
const SizedBox(height: 24),
ElevatedButton(
onPressed: () {
// 验证表单
if (_formKey.currentState!.validate()) {
// 表单验证通过,处理数据
String name = _nameController.text;
String email = _emailController.text;
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('表单提交成功!\n姓名: $name\n邮箱: $email')),
);
}
},
child: const Text('提交表单'),
),
],
),
),
],
),
),
);
}
}
三 代码讲解
这个示例包含了以下内容:
- TextField 示例:基本用法和属性配置使用 TextEditingController 控制输入实时监听输入变化 (onChanged)处理输入完成事件 (onSubmitted)显示当前输入值
- TextFormField 示例:在 Form 组件中使用,配合 GlobalKey 进行表单管理实现了输入验证功能 (validator)不同类型的输入 (文本、邮箱、密码)密码隐藏 (obscureText)表单提交和验证逻辑
通过运行这个示例,你可以直观地看到:
- TextField 是基础输入组件,适合简单的文本输入
- TextFormField 继承自 TextField,增加了表单验证功能,适合在表单中使用
- 如何使用控制器 (Controller) 获取和管理输入值
- 如何实现基本的输入验证逻辑
你可以尝试修改代码中的属性(如 obscureText、maxLength 等),观察它们对输入框行为的影响,加深理解。
四 代码理解
flutter框架编程,被吐槽嵌套代码,但不嵌套的话,整体代码看着更没有章法;怎么说呢,原来使用qt,习惯了UI设计师的用法,还真不习惯用代码直接写界面;
但flutter框架,提倡用代码来写,习惯了就好,html 5也是这样,经常学习,每天调试点代码,习惯了这个框架的开发方式,就好说了!
猜你喜欢
- 2025-08-02 'AI Godfather' Geoffrey Hinton Warns Multimodal Chatbots Are Already Conscious in Shanghai
- 2025-08-02 Win10预览版10532更新内容大全
- 2025-08-02 Win11 安卓子系统 root 项目 MagiskOnWSA 被微软 GitHub 封禁
- 2025-08-02 脉冲雷达用GaN MMIC功率放大器的电源管理
- 2025-08-02 《黑色工作坊》:“让多一点真相浮出水面”
- 2025-08-02 软硬件可能有问题 Win10快速自查会不会?
- 2025-08-02 PLC信号输入和输出怎么区分?
- 2025-08-02 javascript超长知识归纳总结
- 2025-08-02 JavaScript全解析——正则表达式
- 2025-08-02 “偷人和输入”一文,太精辟了,内涵搞笑的段子,口水都笑出来了
- 最近发表
- 标签列表
-
- location.href (44)
- document.ready (36)
- git checkout -b (34)
- 跃点数 (35)
- 阿里云镜像地址 (33)
- qt qmessagebox (36)
- mybatis plus page (35)
- vue @scroll (38)
- 堆栈区别 (33)
- 什么是容器 (33)
- sha1 md5 (33)
- navicat导出数据 (34)
- 阿里云acp考试 (33)
- 阿里云 nacos (34)
- redhat官网下载镜像 (36)
- srs服务器 (33)
- pico开发者 (33)
- https的端口号 (34)
- vscode更改主题 (35)
- 阿里云资源池 (34)
- os.path.join (33)
- redis aof rdb 区别 (33)
- 302跳转 (33)
- http method (35)
- js array splice (33)