
点击相册卡片后,需要进入相册详情页查看里面的照片。
今天来实现这个页面,主要是展示照片网格和相册信息。
页面接收参数
相册详情页需要接收一个相册对象:
dart
class AlbumDetailScreen extends StatelessWidget {
final AlbumModel album;
const AlbumDetailScreen({super.key, required this.album});
通过构造函数接收
AlbumModel对象。这个对象包含相册的名称、分类、描述等信息。
从上一个页面跳转时传过来。
页面基础结构
搭建页面框架:
dart
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(album.name),
actions: [
IconButton(
icon: const Icon(Icons.edit),
onPressed: () => Navigator.push(
context,
MaterialPageRoute(builder: (_) => EditAlbumScreen(album: album)),
),
),
标题直接用相册名称,用户一眼就知道在看哪个相册。
右上角放编辑按钮,点击跳转到编辑页面。
编辑页面可以修改相册名称、分类、描述等。
dart
PopupMenuButton<String>(
onSelected: (value) {
if (value == 'delete') {
_showDeleteDialog(context);
}
},
itemBuilder: (context) => [
const PopupMenuItem(value: 'delete', child: Text('删除相册')),
],
),
],
),
还有一个更多菜单,用
PopupMenuButton实现。目前只有删除功能,点击后弹出确认对话框。
后续可以在这里加更多功能,比如分享、导出等。
主体内容区域
主体用CustomScrollView实现:
dart
body: Consumer<AlbumProvider>(
builder: (context, provider, _) {
final photos = provider.getPhotosByAlbum(album.id);
return CustomScrollView(
slivers: [
SliverToBoxAdapter(
child: _buildAlbumInfo(),
),
用
Consumer监听数据变化,照片增删后会自动刷新。通过
getPhotosByAlbum方法获取当前相册的照片列表。第一个Sliver放相册信息区域。
照片网格展示
根据照片数量显示不同内容:
dart
SliverPadding(
padding: EdgeInsets.all(16.w),
sliver: photos.isEmpty
? SliverToBoxAdapter(
child: Center(
child: Column(
children: [
SizedBox(height: 50.h),
Icon(Icons.photo_library, size: 64.sp, color: Colors.grey[300]),
SizedBox(height: 16.h),
Text('暂无照片', style: TextStyle(color: Colors.grey, fontSize: 16.sp)),
],
),
),
)
如果没有照片,显示空状态提示。
用一个大图标加文字,比空白页面友好。
提示用户这个相册还没有照片。
dart
: SliverGrid(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
mainAxisSpacing: 4.w,
crossAxisSpacing: 4.w,
),
delegate: SliverChildBuilderDelegate(
(context, index) => _buildPhotoItem(context, photos[index]),
childCount: photos.length,
),
),
),
],
);
},
),
);
}
有照片时用三列网格展示。
间距设成4,照片之间紧凑一些,像相册的感觉。
用
SliverChildBuilderDelegate按需构建,性能更好。
相册信息区域
显示相册的分类和描述:
dart
Widget _buildAlbumInfo() {
return Container(
padding: EdgeInsets.all(16.w),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Container(
padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 4.h),
decoration: BoxDecoration(
color: const Color(0xFFE91E63).withOpacity(0.1),
borderRadius: BorderRadius.circular(16.r),
),
child: Text(
album.category,
style: TextStyle(
color: const Color(0xFFE91E63),
fontSize: 12.sp,
),
),
),
分类用标签的形式显示,粉色背景加粉色文字。
圆角16,看起来像一个小标签。
比如"旅行"、"生日"这样的分类。
dart
SizedBox(width: 8.w),
Text(
'${album.photoCount}张照片',
style: TextStyle(
color: Colors.grey,
fontSize: 12.sp,
),
),
],
),
分类旁边显示照片数量。
用灰色小字,作为辅助信息。
dart
if (album.description.isNotEmpty) ...[
SizedBox(height: 12.h),
Text(
album.description,
style: TextStyle(
fontSize: 14.sp,
color: Colors.grey[700],
),
),
],
],
),
);
}
如果有描述就显示,没有就不显示。
用
if加展开运算符...[]来实现条件渲染。描述用深灰色,比标签颜色深一点。
照片项组件
每张照片的展示:
dart
Widget _buildPhotoItem(BuildContext context, PhotoModel photo) {
return InkWell(
onTap: () => Navigator.push(
context,
MaterialPageRoute(builder: (_) => PhotoDetailScreen(photo: photo)),
),
child: Stack(
fit: StackFit.expand,
children: [
Container(
color: _getColorForPhoto(photo.url),
child: Center(
child: Icon(Icons.photo, color: Colors.white.withOpacity(0.5), size: 32.sp),
),
),
点击照片跳转到照片详情页。
用
Stack实现层叠布局,底层是照片,上层是收藏标记。这里用颜色块代替真实图片,加载更快。
dart
if (photo.isFavorite)
Positioned(
top: 4.w,
right: 4.w,
child: Icon(Icons.favorite, color: Colors.red, size: 20.sp),
),
],
),
);
}
如果照片被收藏了,右上角显示红色爱心。
用
Positioned定位到右上角。这样用户一眼就能看出哪些是收藏的照片。
颜色生成方法
根据照片URL生成颜色:
dart
Color _getColorForPhoto(String url) {
final colors = [
Colors.pink[200]!,
Colors.purple[200]!,
Colors.blue[200]!,
Colors.teal[200]!,
Colors.green[200]!,
Colors.orange[200]!,
];
return colors[url.hashCode % colors.length];
}
准备了6种浅色,用哈希值取模选择。
每张照片颜色不同,但同一张照片每次打开颜色固定。
浅色系看起来比较柔和。
删除确认对话框
删除相册前需要确认:
dart
void _showDeleteDialog(BuildContext context) {
showDialog(
context: context,
builder: (context) => AlertDialog(
title: const Text('删除相册'),
content: const Text('确定要删除这个相册吗?相册中的所有照片也会被删除。'),
actions: [
TextButton(
onPressed: () => Navigator.pop(context),
child: const Text('取消'),
),
用
AlertDialog弹出确认框。提示用户删除相册会同时删除里面的照片。
取消按钮关闭对话框。
dart
TextButton(
onPressed: () {
context.read<AlbumProvider>().deleteAlbum(album.id);
Navigator.pop(context);
Navigator.pop(context);
},
child: const Text('删除', style: TextStyle(color: Colors.red)),
),
],
),
);
}
确认删除后调用Provider的
deleteAlbum方法。然后关闭对话框,再返回上一页。
删除按钮用红色,提醒用户这是危险操作。
小结
相册详情页主要是展示照片网格和相册信息。
用三列网格展示照片,收藏的照片右上角有爱心标记。
支持编辑和删除相册,删除前有确认对话框。
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net