import 'package:flutter/material.dart'; /// 照片页面 - 应用主页面 /// 使用CustomScrollView实现弹性滚动和复杂布局 class PhotoPage extends StatelessWidget { const PhotoPage({super.key}); @override Widget build(BuildContext context) { return Scaffold( // 透明AppBar区域,让内容延伸到状态栏 extendBodyBehindAppBar: true, body: CustomScrollView( slivers: [ const PhotoAppBar(), const PhotoFeed(), ], ), ); } } /// 自定义SliverAppBar /// 技巧:使用SliverAppBar实现滚动时的动态效果 class PhotoAppBar extends StatelessWidget { const PhotoAppBar({super.key}); @override Widget build(BuildContext context) { return SliverAppBar( backgroundColor: Colors.transparent, elevation: 0, pinned: true, // 滚动时固定在顶部 floating: true, // 向下滚动时立即显示 snap: false, expandedHeight: 0, title: ShaderMask( // 技巧:使用ShaderMask实现文字渐变效果 shaderCallback: (bounds) => const LinearGradient( colors: [Color(0xFFFF8A1F), Color(0xFFFFBE3D)], begin: Alignment.topLeft, end: Alignment.bottomRight, ).createShader(bounds), child: const Text( 'SnapWish,', style: TextStyle( fontSize: 24, fontWeight: FontWeight.bold, color: Colors.white, // 会被shader覆盖 ), ), ), ); } } /// 照片信息流 /// 使用SliverList实现高效的长列表渲染 class PhotoFeed extends StatelessWidget { const PhotoFeed({super.key}); @override Widget build(BuildContext context) { // 模拟数据 - 实际应用中应从API获取 final mockPhotos = []; // 空数组触发空状态 if (mockPhotos.isEmpty) { return const SliverFillRemaining( child: EmptyState(), ); } return SliverPadding( // 水平内边距,确保内容不贴边 padding: const EdgeInsets.symmetric(horizontal: 16), sliver: SliverList( delegate: SliverChildBuilderDelegate( (context, index) { return const PhotoCard(); }, childCount: mockPhotos.length, ), ), ); } } /// 空状态组件 /// 良好的空状态设计提升用户体验 class EmptyState extends StatelessWidget { const EmptyState({super.key}); @override Widget build(BuildContext context) { return const Center( child: Text( '还没有添加任何图片', style: TextStyle( fontSize: 14, color: Color(0xFF9CA3AF), letterSpacing: 0.5, // 字间距让文字更美观 ), ), ); } } /// 照片卡片组件 - 核心UI元素 /// 使用StatefulWidget管理收藏状态 class PhotoCard extends StatefulWidget { const PhotoCard({super.key}); @override State createState() => _PhotoCardState(); } /// 照片卡片状态管理 /// 技巧:使用AnimationController实现按压动画 class _PhotoCardState extends State with SingleTickerProviderStateMixin { // 收藏状态 bool _isFavorite = false; // 动画控制器 late AnimationController _controller; late Animation _scaleAnimation; @override void initState() { super.initState(); // 初始化动画控制器,时长200ms _controller = AnimationController( duration: const Duration(milliseconds: 200), vsync: this, ); // 创建缩放动画,从1.0到0.98 _scaleAnimation = Tween( begin: 1.0, end: 0.98, ).animate(CurvedAnimation( parent: _controller, curve: Curves.easeInOut, )); } @override void dispose() { _controller.dispose(); super.dispose(); } /// 切换收藏状态 void _toggleFavorite() { setState(() { _isFavorite = !_isFavorite; }); } /// 处理卡片点击 void _handleCardTap() { // TODO: 实现跳转到详情页 debugPrint('跳转到照片详情页'); } @override Widget build(BuildContext context) { final screenWidth = MediaQuery.of(context).size.width; final cardWidth = screenWidth - 32; // 考虑左右16dp内边距 final cardHeight = cardWidth * 4 / 5; // 4:5的宽高比 return GestureDetector( // 按压动画触发 onTapDown: (_) => _controller.forward(), onTapUp: (_) { _controller.reverse(); _handleCardTap(); }, onTapCancel: () => _controller.reverse(), // 双击收藏 onDoubleTap: _toggleFavorite, child: ScaleTransition( scale: _scaleAnimation, child: Container( margin: const EdgeInsets.only(bottom: 14), width: cardWidth, height: cardHeight, decoration: BoxDecoration( borderRadius: BorderRadius.circular(24), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.35), blurRadius: 24, offset: const Offset(0, 8), ), ], ), child: ClipRRect( borderRadius: BorderRadius.circular(24), child: Stack( children: [ // 图片占位符 _buildImagePlaceholder(), // 底部渐变遮罩,提升文字可读性 _buildGradientOverlay(), // 收藏按钮 _buildFavoriteButton(), // 书签装饰 _buildBookmarkDecoration(), // 标签文字 _buildTags(), ], ), ), ), ), ); } /// 构建图片占位符 Widget _buildImagePlaceholder() { return Container( color: Colors.grey[800], child: const Center( child: Icon(Icons.photo, size: 80, color: Colors.grey), ), ); } /// 构建底部渐变遮罩 Widget _buildGradientOverlay() { return Positioned( bottom: 0, left: 0, right: 0, height: 80, child: Container( decoration: BoxDecoration( gradient: LinearGradient( colors: [ Colors.black.withOpacity(0), // 透明 Colors.black.withOpacity(0.6), // 60%不透明 ], begin: Alignment.topCenter, end: Alignment.bottomCenter, ), ), ), ); } /// 构建收藏按钮 Widget _buildFavoriteButton() { return Positioned( top: 12, right: 12, child: GestureDetector( onTap: _toggleFavorite, child: Container( width: 32, height: 32, decoration: BoxDecoration( color: Colors.black.withOpacity(0.35), shape: BoxShape.circle, ), child: Icon( _isFavorite ? Icons.favorite : Icons.favorite_border, color: _isFavorite ? const Color(0xFFFF5A5F) : Colors.white, size: 20, ), ), ), ); } /// 构建书签装饰 Widget _buildBookmarkDecoration() { return Positioned( bottom: 12, left: 12, child: Container( width: 18, height: 18, decoration: BoxDecoration( color: Colors.white.withOpacity(0.2), borderRadius: BorderRadius.circular(4), border: Border.all( color: Colors.white.withOpacity(0.4), width: 1, ), ), ), ); } /// 构建标签文字 Widget _buildTags() { return const Positioned( bottom: 12, right: 12, child: Text( '#家居 #盆栽 #庭院', style: TextStyle( fontSize: 12, color: Colors.white, fontWeight: FontWeight.w600, shadows: [ Shadow( color: Colors.black54, offset: Offset(0, 1), blurRadius: 2, ), ], ), ), ); } } /// 照片详情页面 /// 提供全屏浏览和交互功能 class PhotoDetailPage extends StatefulWidget { final List photos; final int initialIndex; const PhotoDetailPage({ super.key, required this.photos, required this.initialIndex, }); @override State createState() => _PhotoDetailPageState(); } class _PhotoDetailPageState extends State { // 当前照片索引 late int _currentIndex; // 页面控制器,用于控制PageView late PageController _pageController; @override void initState() { super.initState(); _currentIndex = widget.initialIndex; _pageController = PageController(initialPage: _currentIndex); } @override void dispose() { _pageController.dispose(); super.dispose(); } /// 显示操作反馈 void _showActionFeedback(String message) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text(message)), ); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.black, appBar: AppBar( backgroundColor: Colors.transparent, elevation: 0, actions: [ _buildActionButton(Icons.favorite_border, '收藏功能待实现'), _buildActionButton(Icons.share, '分享功能待实现'), _buildActionButton(Icons.delete, '删除功能待实现'), ], ), body: Stack( children: [ // 照片浏览区域 _buildPhotoViewer(), // 页码指示器 _buildPageIndicator(), ], ), ); } /// 构建操作按钮 Widget _buildActionButton(IconData icon, String feedback) { return IconButton( icon: Icon(icon), onPressed: () => _showActionFeedback(feedback), ); } /// 构建照片查看器 Widget _buildPhotoViewer() { return PageView.builder( controller: _pageController, itemCount: widget.photos.length, onPageChanged: (index) { setState(() { _currentIndex = index; }); }, itemBuilder: (context, index) { return Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Container( width: MediaQuery.of(context).size.width, height: MediaQuery.of(context).size.height * 0.7, color: Colors.grey[800], child: const Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon(Icons.photo, size: 100, color: Colors.white), SizedBox(height: 20), Text( '照片占位符', style: TextStyle( color: Colors.white, fontSize: 24, ), ), ], ), ), ), ], ), ); }, ); } /// 构建页码指示器 Widget _buildPageIndicator() { return Positioned( bottom: 20, left: 0, right: 0, child: Center( child: Text( '${_currentIndex + 1} / ${widget.photos.length}', style: const TextStyle( color: Colors.white, fontSize: 16, ), ), ), ); } }