Flutter---个人信息(2)---实现修改昵称
效果图:点击修改昵称,修改后主页面和子页面都显示该名称



整体架构
HomePage (首页)
↓ (传递回调函数)
PersonInformationPage (个人信息页)
↓ (打开对话框)
ChangeNameDialog (修改名字弹窗)
↓ (用户确认)
数据回传
用户交互流程
用户点击昵称行 
→ 打开修改弹窗 
→ 输入新名字 
→ 点击确定 
→ 验证数据 
→ 更新状态 
→ 回调通知 
→ 关闭弹窗
关键代码
// 定义回调接口
final Function(String) onNameChanged;// 使用回调
widget.onNameChanged(newName);状态管理三层架构
// 第一层:弹窗内部状态
setState(() {_name = newName; // 更新个人信息页的显示
});// 第二层:回调父组件
widget.onNameChanged(newName); // 通知首页更新// 第三层:首页状态更新
onNameChanged: (newName) {setState(() {_homeName = newName; // 更新首页数据});
}数据流
用户输入 ↓ 
TextField → TextEditingController ↓ 
数据验证 (trim + isNotEmpty) ↓ 
更新本地状态 (setState) ↓ 
回调父组件 (onNameChanged) ↓ 
更新首页状态 ↓ 
关闭弹窗 (Navigator.pop)实现步骤
1.添加回调函数
final Function(String) onNameChanged; //1,添加回调函数2.添加必须传入的名字回调函数
const PersonInformationPage({super.key,required this.onNameChanged});//2.添加必须传入的名字回调函数3.添加文本控制器,控制用户输入的文本
final TextEditingController _nameController = TextEditingController();//3.添加文本控制器4.初始化控制器
@overridevoid initState(){super.initState();_nameController.text = _name;}5.清理控制器
//5.清理控制器@overridevoid dispose(){_nameController.dispose();super.dispose();}6.在昵称这一行添加点击事件(修改名字的弹窗)
              onTap: () {// 6.增加修改名字的弹窗ChangeNameDialog();},7.定义修改名字的弹窗
//7.定义修改名字的弹窗//========================修改名字的弹窗========================================//void ChangeNameDialog() {_nameController.text = _name; //设置当前名字到输入框showDialog(context: context,builder: (builder) {return Dialog(shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(26),),child: Container(width: 263,padding: EdgeInsets.only(top: 20,bottom: 29,left: 34,right: 34),decoration: BoxDecoration(color: Colors.white, //背景颜色borderRadius: BorderRadius.circular(26),),child: Column(mainAxisSize: MainAxisSize.min,crossAxisAlignment: CrossAxisAlignment.start,children: [Row(mainAxisAlignment: MainAxisAlignment.center,children: [Text("修改昵称",style: const TextStyle(color: Colors.black,fontSize: 22,fontWeight: FontWeight.bold,),),],),SizedBox(height: 16),Container(padding: EdgeInsets.symmetric(horizontal: 12),decoration: BoxDecoration(color: Color(0xFFD8D8D8),//输入框颜色borderRadius: BorderRadius.circular(7),),child: TextField( //创建文本输入框组件controller: _nameController, //控制器:用于获取或者设置输入框文本内容style: TextStyle(color: Colors.white),decoration: InputDecoration(//hintText: "请输入",//提示性文字hintStyle: TextStyle(color: Colors.white54),border: InputBorder.none,),),),SizedBox(height: 20),Row(children: [//取消按钮Expanded(child: Container(height: 44, // 固定高度child: TextButton(onPressed: () => Navigator.pop(context),style: TextButton.styleFrom(backgroundColor: Color(0xFFD8D8D8),shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(26),),),child: Text("取消",style: TextStyle(color: Color(0xFF3D3D3D), fontSize: 16),),),),),SizedBox(width: 50),//确定按钮Expanded(child: Container(height: 44, // 固定高度child: TextButton(onPressed: () {//确定按钮具体的实现逻辑if(_nameController.text.trim().isNotEmpty){ //检查输入框内容是否非空String newName = _nameController.text.trim(); //获取输入框的文本内容setState(() {_name = newName; //当前页面状态,触发界面重绘});widget.onNameChanged(newName); //调用回调函数通知首页(home_page)Navigator.pop(context);//关闭对话框}},style: TextButton.styleFrom(backgroundColor: Color(0xff1F8FFF),shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(26),),),child: Text("确定",style: TextStyle(color: Colors.white, fontSize: 16),),),),),],)],),),);},).then((value) { //处理异步操作完成后的回调if(value != null && mounted) { //检查返回的结果不为空 && 检查当前组件是否还在挂载状态(避免在组件销毁后更新状态)Navigator.pop(context, value); //返回上一页并传递数据}});}8.回到主页面(home_page)设置获取回调的名称且设置UI重建
//8.获取回调过来的昵称Navigator.push(context, MaterialPageRoute(builder: (context)=> PersonInformationPage(onNameChanged: (newName) {setState(() {_homeName = newName;//更新首页名字变量,引发UI重建});},)));完整代码(实现修改名字的弹窗)
home_page.dart
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:my_flutter/person_information_page.dart';class HomePage extends StatefulWidget {const HomePage({super.key});@overrideState<StatefulWidget> createState() => _HomePageState();
}class _HomePageState extends State<HomePage> {var _homeGender = "男"; //性别var _homeName = "西西没烦恼"; //昵称var _homeBirthday = "2000-01-01"; // 出生年月var _homeHeight = "183"; // 身高// =======================计算具体年龄的方法=================================int get _age {try {//将字符串格式的生日(如 "2000-01-01")转换为 DateTime对象final birthDate = DateTime.parse(_homeBirthday);final now = DateTime.now(); //获取当前日期时间int age = now.year - birthDate.year; //计算基础年龄(虚岁)if (now.month < birthDate.month || (now.month == birthDate.month && now.day < birthDate.day)) { //判断是否已过生日(实岁)age--;}return age;} catch (e) {return 23; // 默认年龄}}//构建UI@overrideWidget build(BuildContext context) {return Scaffold(body: Container(height: double.infinity,padding: const EdgeInsets.all(16),// 主页背景颜色decoration: const BoxDecoration(gradient: LinearGradient(//渐变begin: Alignment.topCenter,end: Alignment.centerRight,colors: [Color(0xFF62F4F4),Color(0xFFF6F7F9),],),),child: SingleChildScrollView( //可滚动的页面physics: const ClampingScrollPhysics(),child: Column(crossAxisAlignment: CrossAxisAlignment.start,children: [// 个人信息buildUserInfo(),const SizedBox(height: 25),],),),),);}//=======================个人信息的UI=====================================Widget buildUserInfo() {return Column(mainAxisAlignment: MainAxisAlignment.center,children: [const SizedBox(height: 96),// 头像:讲图片裁剪成圆形ClipOval(child: Image.asset("assets/images/apple.png",width: 90,height: 90,fit: BoxFit.cover,),),const SizedBox(height: 8),// 昵称Row(mainAxisAlignment: MainAxisAlignment.center,children: [GestureDetector(onTap: () {  //点击跳转个人信息详情页面//8.获取回调过来的昵称Navigator.push(context, MaterialPageRoute(builder: (context)=> PersonInformationPage(onNameChanged: (newName) {setState(() {_homeName = newName;//更新首页名字变量,引发UI重建});},)));},child: Row(mainAxisAlignment: MainAxisAlignment.center,children: [Text(_homeName, // 名字style: TextStyle(color: const Color(0xFF3D3D3D),fontWeight: FontWeight.bold,fontSize: 24,),),const SizedBox(width: 10),Image.asset("assets/images/cherry.png",width: 20,height: 20,),],),),],),const SizedBox(height: 8),// 个人资料Row(mainAxisAlignment: MainAxisAlignment.center,children: [Text(_homeGender, //性别style: TextStyle(color: const Color(0xFF3D3D3D), fontSize: 16),),// 竖线分隔符Container(width: 1,height: 16,margin: const EdgeInsets.symmetric(horizontal: 12),color: const Color(0xFFD8D8D8),),Text("${_age}岁", // 年龄style: TextStyle(color: const Color(0xFF3D3D3D), fontSize: 16),),// 竖线分隔符Container(width: 1,height: 16,margin: const EdgeInsets.symmetric(horizontal: 12),color: const Color(0xFFD8D8D8),),Text(_homeHeight,//身高style: TextStyle(color: const Color(0xFF3D3D3D), fontSize: 16),),Text("cm",style: TextStyle(color: const Color(0xFF3D3D3D), fontSize: 16),),],),],);}}personal_information_page.dart
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';class PersonInformationPage extends StatefulWidget {const PersonInformationPage({super.key,required this.onNameChanged});//2.添加必须传入的名字回调函数final Function(String) onNameChanged; //1,添加回调函数@overrideState<StatefulWidget> createState() => _PersonInformationPageState();
}class _PersonInformationPageState extends State<PersonInformationPage> {var _selectedGender = "男";//性别var _name = "西西没烦恼"; //昵称var _birthday = "2025-10-01";//初始日期var _height = "183"; //身高final TextEditingController _nameController = TextEditingController();//3.添加文本控制器//4.初始化控制器@overridevoid initState(){super.initState();_nameController.text = _name;}//5.清理控制器@overridevoid dispose(){_nameController.dispose();super.dispose();}// 构建UI@overrideWidget build(BuildContext context) {return Scaffold(body: Container(height: double.infinity,padding: const EdgeInsets.all(16),// 主页背景颜色decoration: const BoxDecoration(gradient: LinearGradient( //颜色渐变begin: Alignment.topCenter,end: Alignment.centerRight,colors: [Color(0xFF62F4F4),Color(0xFFF7F7F9),],),),child: SingleChildScrollView( //可滚动的页面child: Column(mainAxisAlignment: MainAxisAlignment.start,children: [const SizedBox(height: 96),// 头像:裁剪成圆形ClipOval(child: Image.asset("assets/images/apple.png",width: 90,height: 90,fit: BoxFit.cover,),),const SizedBox(height: 8),Row(mainAxisAlignment: MainAxisAlignment.center,children: [Text("点击更换头像",style: TextStyle(color: const Color(0xFF3D3D3D),fontWeight: FontWeight.bold,fontSize: 24,),),const SizedBox(width: 10),],),const SizedBox(height: 8),Text("点击可更换个人信息",style: TextStyle(color: const Color(0xFF3D3D3D).withOpacity(0.6),fontSize: 12,),),const SizedBox(height: 38),// 个人信息列表buildListInformation(),],),),),);}//===========================个人信息列表=======================================//Widget buildListInformation() {return Padding(padding: const EdgeInsets.only(top: 10),child: Container(padding: const EdgeInsets.symmetric(horizontal: 30, vertical: 31),decoration: BoxDecoration(color: Colors.white,borderRadius: BorderRadius.circular(30),),child: Column(mainAxisAlignment: MainAxisAlignment.center,children: [// 昵称GestureDetector(onTap: () {// 6.增加修改名字的弹窗ChangeNameDialog();},child: Row(children: [Text("昵称",style: TextStyle(fontSize: 16, color: Color(0xFF3D3D3D)),),const Spacer(),Text(_name,style: TextStyle(color: Color(0xFF3D3D3D).withOpacity(0.6),fontSize: 14,),),const SizedBox(width: 6),Image.asset("assets/images/cherry.png",width: 30,height: 30,),],),),const SizedBox(height: 28),// 性别GestureDetector(onTap: () {},child: Row(children: [Text("性别",style: TextStyle(fontSize: 16, color: Color(0xFF3D3D3D)),),const Spacer(),Text(_selectedGender, // 显示当前选中性别style: TextStyle(color: Color(0xFF3D3D3D).withOpacity(0.6),fontSize: 14,),),const SizedBox(width: 6),Image.asset("assets/images/cherry.png",width: 30,height: 30,),],),),const SizedBox(height: 28),// 生日GestureDetector(onTap: () {},child: Row(children: [Text("生日",style: TextStyle(fontSize: 16, color: Color(0xFF3D3D3D)),),const Spacer(),Text(_birthday,style: TextStyle(color: Color(0xFF3D3D3D).withOpacity(0.6),fontSize: 14,),),const SizedBox(width: 6),Image.asset("assets/images/cherry.png",width: 30,height: 30,),],),),const SizedBox(height: 28),// 身高GestureDetector(onTap: () {},child: Row(children: [Text("身高",style: TextStyle(fontSize: 16, color: Color(0xFF3D3D3D)),),const Spacer(),Text(_height,style: TextStyle(color: Color(0xFF3D3D3D).withOpacity(0.6),fontSize: 14,),),Text("cm",style: TextStyle(color: Color(0xFF3D3D3D).withOpacity(0.6),fontSize: 14,),),const SizedBox(width: 6),Image.asset("assets/images/cherry.png",width: 30,height: 30,),],),),],),),);}//7.定义修改名字的弹窗//========================修改名字的弹窗========================================//void ChangeNameDialog() {_nameController.text = _name; //设置当前名字到输入框showDialog(context: context,builder: (builder) {return Dialog(shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(26),),child: Container(width: 263,padding: EdgeInsets.only(top: 20,bottom: 29,left: 34,right: 34),decoration: BoxDecoration(color: Colors.white, //背景颜色borderRadius: BorderRadius.circular(26),),child: Column(mainAxisSize: MainAxisSize.min,crossAxisAlignment: CrossAxisAlignment.start,children: [Row(mainAxisAlignment: MainAxisAlignment.center,children: [Text("修改昵称",style: const TextStyle(color: Colors.black,fontSize: 22,fontWeight: FontWeight.bold,),),],),SizedBox(height: 16),Container(padding: EdgeInsets.symmetric(horizontal: 12),decoration: BoxDecoration(color: Color(0xFFD8D8D8),//输入框颜色borderRadius: BorderRadius.circular(7),),child: TextField( //创建文本输入框组件controller: _nameController, //控制器:用于获取或者设置输入框文本内容style: TextStyle(color: Colors.white),decoration: InputDecoration(//hintText: "请输入",//提示性文字hintStyle: TextStyle(color: Colors.white54),border: InputBorder.none,),),),SizedBox(height: 20),Row(children: [//取消按钮Expanded(child: Container(height: 44, // 固定高度child: TextButton(onPressed: () => Navigator.pop(context),style: TextButton.styleFrom(backgroundColor: Color(0xFFD8D8D8),shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(26),),),child: Text("取消",style: TextStyle(color: Color(0xFF3D3D3D), fontSize: 16),),),),),SizedBox(width: 50),//确定按钮Expanded(child: Container(height: 44, // 固定高度child: TextButton(onPressed: () {//确定按钮具体的实现逻辑if(_nameController.text.trim().isNotEmpty){ //检查输入框内容是否非空String newName = _nameController.text.trim(); //获取输入框的文本内容setState(() {_name = newName; //当前页面状态,触发界面重绘});widget.onNameChanged(newName); //调用回调函数通知首页(home_page)Navigator.pop(context);//关闭对话框}},style: TextButton.styleFrom(backgroundColor: Color(0xff1F8FFF),shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(26),),),child: Text("确定",style: TextStyle(color: Colors.white, fontSize: 16),),),),),],)],),),);},).then((value) { //处理异步操作完成后的回调if(value != null && mounted) { //检查返回的结果不为空 && 检查当前组件是否还在挂载状态(避免在组件销毁后更新状态)Navigator.pop(context, value); //返回上一页并传递数据}});}}