282 lines
7.7 KiB
Dart
282 lines
7.7 KiB
Dart
import 'package:flutter/material.dart';
|
||
|
||
/// 添加照片页面 - 照片上传和元数据管理
|
||
/// 提供照片选择、分类选择、标签添加等功能
|
||
/// 使用StatefulWidget管理复杂的表单状态
|
||
class AddPhotoPage extends StatefulWidget {
|
||
const AddPhotoPage({super.key});
|
||
|
||
@override
|
||
State<AddPhotoPage> createState() => _AddPhotoPageState();
|
||
}
|
||
|
||
/// 添加照片页面状态管理
|
||
/// 技巧:使用多个Controller管理不同输入字段
|
||
class _AddPhotoPageState extends State<AddPhotoPage> {
|
||
// 表单状态管理
|
||
String? _selectedCategory;
|
||
final TextEditingController _tagsController = TextEditingController();
|
||
final List<String> _tags = [];
|
||
|
||
// TODO: 替换为真实文件夹数据
|
||
final List<String> _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<String>(
|
||
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),
|
||
);
|
||
}
|
||
} |