import 'package:flutter/material.dart'; /// 添加照片页面 - 照片上传和元数据管理 /// 提供照片选择、分类选择、标签添加等功能 /// 使用StatefulWidget管理复杂的表单状态 class AddPhotoPage extends StatefulWidget { const AddPhotoPage({super.key}); @override State createState() => _AddPhotoPageState(); } /// 添加照片页面状态管理 /// 技巧:使用多个Controller管理不同输入字段 class _AddPhotoPageState extends State { // 表单状态管理 String? _selectedCategory; final TextEditingController _tagsController = TextEditingController(); final List _tags = []; // TODO: 替换为真实文件夹数据 final List _categories = ['默认分类', '人像', '风景', '建筑']; @override void dispose() { _tagsController.dispose(); super.dispose(); } /// 选择照片 /// TODO: 集成图片选择器(image_picker)实现真实功能 void _selectPhoto() { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('选择照片功能待实现')), ); } /// 添加标签 /// 技巧:自动去除空格和重复标签,保持数据整洁 void _addTag(String text) { final tag = text.trim(); if (tag.isNotEmpty && !_tags.contains(tag)) { setState(() { _tags.add(tag); }); _tagsController.clear(); } } /// 移除标签 void _removeTag(String tag) { setState(() { _tags.remove(tag); }); } /// 保存照片 /// 技巧:表单验证确保必要字段已填写 void _savePhoto() { if (_selectedCategory == null) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('请选择文件夹')), ); return; } // TODO: 实现真实保存逻辑 ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('照片已保存到 $_selectedCategory')), ); Navigator.pop(context); } @override Widget build(BuildContext context) { return Scaffold( appBar: _buildAppBar(), body: _buildBody(), ); } /// 构建应用栏 /// 技巧:使用actions添加保存按钮,保持界面简洁 AppBar _buildAppBar() { return AppBar( title: const Text('添加照片'), actions: [ TextButton( onPressed: _savePhoto, child: const Text( '保存', style: TextStyle(color: Colors.white, fontSize: 16), ), ), ], ); } /// 构建页面主体 /// 技巧:使用SingleChildScrollView确保键盘弹出时内容可滚动 Widget _buildBody() { return SingleChildScrollView( padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ _buildPhotoSelector(), const SizedBox(height: 24), _buildCategorySelector(), const SizedBox(height: 24), _buildTagsSection(), ], ), ); } /// 构建照片选择器 /// 技巧:使用GestureDetector实现点击区域,提升用户体验 Widget _buildPhotoSelector() { return GestureDetector( onTap: _selectPhoto, child: Container( height: 200, decoration: BoxDecoration( color: const Color(0xFF1A1D1F), borderRadius: BorderRadius.circular(16), border: Border.all(color: const Color(0xFF374151)), ), child: const Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon( Icons.add_photo_alternate, size: 48, color: Color(0xFF9CA3AF), ), SizedBox(height: 8), Text( '点击选择照片', style: TextStyle( color: Color(0xFF9CA3AF), fontSize: 16, ), ), ], ), ), ), ); } /// 构建分类选择器 /// 技巧:使用DropdownButtonFormField提供下拉选择体验 Widget _buildCategorySelector() { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text( '选择文件夹', style: TextStyle( fontSize: 16, fontWeight: FontWeight.bold, color: Colors.white, ), ), const SizedBox(height: 8), DropdownButtonFormField( value: _selectedCategory, decoration: InputDecoration( border: OutlineInputBorder( borderRadius: BorderRadius.circular(12), ), hintText: '请选择文件夹', filled: true, fillColor: const Color(0xFF1A1D1F), ), dropdownColor: const Color(0xFF1A1D1F), items: _categories.map((category) { return DropdownMenuItem( value: category, child: Text(category, style: const TextStyle(color: Colors.white)), ); }).toList(), onChanged: (value) { setState(() { _selectedCategory = value; }); }, ), ], ); } /// 构建标签区域 /// 技巧:使用Wrap实现标签的流式布局 Widget _buildTagsSection() { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text( '添加标签', style: TextStyle( fontSize: 16, fontWeight: FontWeight.bold, color: Colors.white, ), ), const SizedBox(height: 8), _buildTagInput(), const SizedBox(height: 12), _buildTagList(), ], ); } /// 构建标签输入框 /// 技巧:使用TextField的多种事件处理实现智能标签输入 Widget _buildTagInput() { return TextField( controller: _tagsController, decoration: InputDecoration( border: OutlineInputBorder( borderRadius: BorderRadius.circular(12), ), hintText: '输入标签(支持 #标签 格式)', filled: true, fillColor: const Color(0xFF1A1D1F), suffixIcon: IconButton( icon: const Icon(Icons.add, color: Color(0xFFFF8A1F)), onPressed: () => _addTag(_tagsController.text), ), ), style: const TextStyle(color: Colors.white), onSubmitted: _addTag, onChanged: _handleTagInputChange, ); } /// 处理标签输入变化 /// 技巧:智能识别#符号,支持多种输入格式 void _handleTagInputChange(String value) { // 支持空格或回车分隔标签 if (value.endsWith(' ') || value.endsWith('\n')) { final tag = value.trim(); if (tag.isNotEmpty) { _addTag(tag.replaceAll('#', '')); } } } /// 构建标签列表 /// 技巧:使用Chip组件实现可删除的标签 Widget _buildTagList() { if (_tags.isEmpty) { return const Text( '暂无标签,可添加多个标签方便搜索', style: TextStyle(color: Color(0xFF9CA3AF), fontSize: 14), ); } return Wrap( spacing: 8, runSpacing: 8, children: _tags.map((tag) => _buildTagChip(tag)).toList(), ); } /// 构建单个标签Chip /// 技巧:自定义Chip样式,提升视觉体验 Widget _buildTagChip(String tag) { return Chip( label: Text( '#$tag', style: const TextStyle(color: Colors.white, fontSize: 12), ), backgroundColor: const Color(0xFF374151), deleteIcon: const Icon(Icons.close, size: 16, color: Colors.white), onDeleted: () => _removeTag(tag), ); } }