flutter_for_openharmony家庭相册app实战+相册详情实现

点击相册卡片后,需要进入相册详情页查看里面的照片。

今天来实现这个页面,主要是展示照片网格和相册信息。

页面接收参数

相册详情页需要接收一个相册对象:

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

相关推荐
灰灰勇闯IT2 小时前
Flutter for OpenHarmony:弹窗与对话框(Dialog)—— 构建清晰的上下文交互
flutter·交互
qq_177767372 小时前
React Native鸿蒙跨平台通过Animated.Value.interpolate实现滚动距离到动画属性的映射
javascript·react native·react.js·harmonyos
晚霞的不甘2 小时前
Flutter for OpenHarmony从零到一:构建《冰火人》双人合作闯关游戏
android·flutter·游戏·前端框架·全文检索·交互
2601_949833392 小时前
flutter_for_openharmony口腔护理app实战+饮食记录实现
android·javascript·flutter
2601_949480062 小时前
【无标题】
开发语言·前端·javascript
css趣多多2 小时前
Vue过滤器
前端·javascript·vue.js
jian110582 小时前
Android studio 调试flutter 运行自己的苹果手机上
flutter·智能手机·android studio
向哆哆2 小时前
高校四六级报名管理系统的考试信息模块实现:Flutter × OpenHarmony 跨端开发实践
flutter·开源·鸿蒙·openharmony·开源鸿蒙
jian110582 小时前
Android studio配置flutter,mac Android studio 发现苹果手机设备
android·flutter·android studio