Flutter for OpenHarmony 看书管理记录App实战:编辑书籍实现
Flutter书籍编辑页面实现 编辑页面在添加页面基础上增加了数据回显、评分修改和删除功能。使用TextEditingController预填已有书籍数据,右上角添加删除按钮并二次确认。页面布局包含封面区域(可更换)、表单输入区(书名/作者等)、阅读状态选择、评分修改(5星评分)和提交按钮。关键点: 通过控制器管理表单数据 删除操作需弹窗确认 评分组件支持修改 生命周期中销毁控制器防内存泄漏 表单
编辑书籍页面和添加页面很像,但需要回显已有数据,还要支持删除功能。今天来实现这个页面,主要涉及数据回显、评分修改、删除确认等功能。
编辑页面比添加页面多了几个功能:回显已有数据、修改评分、删除书籍。这些功能让用户可以完整地管理自己的书籍信息。
页面整体结构
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
class EditBookPage extends StatefulWidget {
const EditBookPage({super.key});
State<EditBookPage> createState() => _EditBookPageState();
}
和添加页面一样用 StatefulWidget,因为有表单状态需要管理。
状态变量和控制器
class _EditBookPageState extends State<EditBookPage> {
final _formKey = GlobalKey<FormState>();
String _status = '在读';
String _category = '文学';
final _titleController = TextEditingController(text: '百年孤独');
final _authorController = TextEditingController(text: '加西亚·马尔克斯');
final _publisherController = TextEditingController(text: '南海出版公司');
final _pagesController = TextEditingController(text: '380');
和添加页面不同的是,这里用 TextEditingController 来控制输入框的值,并且在初始化时就填入已有数据。实际项目中这些数据应该从路由参数或数据库获取。
生命周期管理
void dispose() {
_titleController.dispose();
_authorController.dispose();
_publisherController.dispose();
_pagesController.dispose();
super.dispose();
}
TextEditingController 需要在 dispose 中销毁,防止内存泄漏。这是 Flutter 开发的基本规范。
AppBar 配置
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: const Color(0xFFFDF8F3),
appBar: AppBar(
title: const Text('编辑书籍'),
backgroundColor: const Color(0xFF5B4636),
foregroundColor: Colors.white,
actions: [
IconButton(icon: const Icon(Icons.delete_outline), onPressed: () => _showDeleteDialog()),
],
),
右上角放了删除按钮,点击后弹出确认对话框。删除是危险操作,需要二次确认。
页面内容布局
body: SingleChildScrollView(
padding: EdgeInsets.all(16.w),
child: Form(
key: _formKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_buildCoverSection(),
SizedBox(height: 20.h),
_buildFormSection(),
SizedBox(height: 20.h),
_buildStatusSection(),
SizedBox(height: 20.h),
_buildRatingSection(),
SizedBox(height: 30.h),
_buildSubmitButton(),
],
),
),
),
);
}
比添加页面多了一个评分模块,因为编辑时用户可能想修改自己对这本书的评分。
封面编辑区域
Widget _buildCoverSection() {
return Center(
child: Stack(
children: [
Container(
width: 120.w, height: 160.h,
decoration: BoxDecoration(
color: const Color(0xFF5B4636).withOpacity(0.1),
borderRadius: BorderRadius.circular(12.r),
),
child: Icon(Icons.menu_book, size: 60.sp, color: const Color(0xFF5B4636)),
),
Positioned(
right: 0, bottom: 0,
child: Container(
padding: EdgeInsets.all(6.w),
decoration: const BoxDecoration(color: Color(0xFF5B4636), shape: BoxShape.circle),
child: Icon(Icons.camera_alt, size: 16.sp, color: Colors.white),
),
),
],
),
);
}
封面区域用 Stack 叠加一个相机图标,表示可以更换封面。和添加页面的虚线框不同,这里显示的是已有的封面(用图标代替)。
表单输入区域
Widget _buildFormSection() {
return Container(
padding: EdgeInsets.all(16.w),
decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(12.r)),
child: Column(
children: [
_buildTextField('书名', _titleController, Icons.menu_book),
SizedBox(height: 16.h),
_buildTextField('作者', _authorController, Icons.person),
SizedBox(height: 16.h),
_buildTextField('出版社', _publisherController, Icons.business),
SizedBox(height: 16.h),
_buildTextField('总页数', _pagesController, Icons.format_list_numbered, keyboardType: TextInputType.number),
SizedBox(height: 16.h),
_buildDropdown('分类', _category, ['文学', '历史', '科技', '经济', '哲学', '心理', '艺术', '其他'], (v) => setState(() => _category = v!)),
],
),
);
}
表单字段和添加页面类似,但输入框绑定了 TextEditingController,会自动显示已有数据。
文本输入组件
Widget _buildTextField(String label, TextEditingController controller, IconData icon, {TextInputType? keyboardType}) {
return TextFormField(
controller: controller,
keyboardType: keyboardType,
decoration: InputDecoration(
labelText: label,
prefixIcon: Icon(icon, color: const Color(0xFF5B4636)),
border: OutlineInputBorder(borderRadius: BorderRadius.circular(8.r)),
focusedBorder: OutlineInputBorder(borderRadius: BorderRadius.circular(8.r), borderSide: const BorderSide(color: Color(0xFF5B4636), width: 2)),
),
);
}
和添加页面的区别是这里接收 TextEditingController 而不是 hint 文字。
评分修改模块
Widget _buildRatingSection() {
return Container(
padding: EdgeInsets.all(16.w),
decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(12.r)),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('我的评分', style: TextStyle(fontSize: 16.sp, fontWeight: FontWeight.bold, color: const Color(0xFF3D2914))),
SizedBox(height: 12.h),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: List.generate(5, (i) => GestureDetector(
onTap: () {},
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 4.w),
child: Icon(i < 4 ? Icons.star : Icons.star_border, color: Colors.amber, size: 36.sp),
),
)),
),
],
),
);
}
评分用五颗星显示,点击可以修改评分。星星比较大(36.sp),方便点击。实心星表示已评分,空心星表示未评分。
提交按钮
Widget _buildSubmitButton() {
return SizedBox(
width: double.infinity,
child: ElevatedButton(
onPressed: () { Get.back(); Get.snackbar('成功', '书籍信息已更新'); },
style: ElevatedButton.styleFrom(
backgroundColor: const Color(0xFF5B4636),
foregroundColor: Colors.white,
padding: EdgeInsets.symmetric(vertical: 16.h),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12.r))
),
child: Text('保存修改', style: TextStyle(fontSize: 16.sp)),
),
);
}
按钮文字改成"保存修改",和添加页面的"保存"区分开。
删除确认对话框
void _showDeleteDialog() {
Get.dialog(AlertDialog(
title: const Text('删除书籍'),
content: const Text('确定要删除这本书吗?相关的阅读记录和笔记也会被删除。'),
actions: [
TextButton(onPressed: () => Get.back(), child: const Text('取消')),
TextButton(
onPressed: () { Get.back(); Get.back(); Get.snackbar('已删除', '书籍已删除'); },
child: const Text('删除', style: TextStyle(color: Colors.red))
),
],
));
}
}
删除对话框提醒用户相关数据也会被删除,让用户做出知情决定。确认按钮用红色文字强调危险性。
Get.back() 调用两次:第一次关闭对话框,第二次返回上一页。
数据回显的实现
实际项目中,编辑页面的数据应该从路由参数获取:
// 示例:从路由参数获取书籍ID
// final bookId = Get.arguments['id'];
// 然后从数据库查询书籍信息
// final book = await db.getBook(bookId);
// 再用 setState 更新控制器的值
目前数据是写死的,后面接入数据库时再改。
编辑和添加的区别
编辑页面和添加页面的主要区别:
数据回显:编辑页面需要显示已有数据,添加页面是空白的。
删除功能:编辑页面有删除按钮,添加页面没有。
评分功能:编辑页面可以修改评分,添加页面通常不需要评分(还没读呢)。
按钮文字:编辑是"保存修改",添加是"保存"。
小结
编辑书籍页面在添加页面的基础上增加了数据回显、评分修改、删除功能。用 TextEditingController 控制输入框的值,用对话框确认删除操作。
下一篇会讲书架列表页面的实现,涉及到网格布局和颜色选择,敬请期待。
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net
更多推荐

所有评论(0)