在这里插入图片描述

前言

收藏夹功能让用户可以保存感兴趣的青花瓷藏品,方便日后查看和学习。我们将实现一个支持分组管理、批量操作和同步功能的收藏系统,让用户能够有效地组织自己的收藏内容。

收藏是用户与内容建立深度连接的方式,一个好的收藏系统不仅要方便添加和查看,还要支持用户按照自己的方式组织内容。我们借鉴了传统收藏家整理藏品的方式,提供分类和标签功能。

收藏数据模型

定义收藏项的数据模型,包含藏品信息和收藏元数据。

// lib/models/favorite_item.dart
class FavoriteItem {
  final String id;
  final String porcelainId;
  final String porcelainName;
  final String imageUrl;
  final DateTime addedAt;
  final String? folderId;
  final String? note;

  const FavoriteItem({
    required this.id,
    required this.porcelainId,
    required this.porcelainName,
    required this.imageUrl,
    required this.addedAt,
    this.folderId,
    this.note,
  });
}


收藏数据模型包含了管理收藏所需的全部信息:`porcelainId`关联原始藏品,`addedAt`记录收藏时间用于排序,`folderId`支持分组管理,`note`允许用户添加个人备注。可选参数使用`?`标记,提供了灵活性。

## 收藏夹页面结构

收藏夹页面展示用户收藏的所有藏品,支持分组查看和管理操作。

```dart
// lib/screens/favorites/favorites_screen.dart
import 'package:flutter/material.dart';

class FavoritesScreen extends StatefulWidget {
  const FavoritesScreen({super.key});

  
  State<FavoritesScreen> createState() => _FavoritesScreenState();
}

class _FavoritesScreenState extends State<FavoritesScreen> {
  bool _isEditMode = false;
  final Set<String> _selectedIds = {};

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('我的收藏'),
        actions: [
          TextButton(
            onPressed: () {
              setState(() => _isEditMode = !_isEditMode);
            },
            child: Text(_isEditMode ? '完成' : '编辑'),
          ),
        ],
      ),
      body: FavoritesList(
        isEditMode: _isEditMode,
        selectedIds: _selectedIds,
        onSelectionChanged: (ids) {
          setState(() => _selectedIds.clear()..addAll(ids));
        },
      ),
    );
  }
}

收藏夹页面支持编辑模式,用户可以批量选择和删除收藏。_isEditMode控制是否处于编辑状态,_selectedIds存储选中的收藏项ID。应用栏的编辑按钮切换编辑模式,这种设计符合用户的操作习惯。

OpenHarmony收藏页面

在OpenHarmony端实现收藏夹页面,使用List组件展示收藏列表。

// ohos/entry/src/main/ets/pages/FavoritesPage.ets
@Entry
@Component
struct FavoritesPage {
  @State isEditMode: boolean = false;
  @State selectedIds: string[] = [];

  build() {
    Column() {
      Row() {
        Text('我的收藏')
          .fontSize(20)
          .fontWeight(FontWeight.Bold)
        Blank()
        Text(this.isEditMode ? '完成' : '编辑')
          .fontColor('#1E4B8E')
          .onClick(() => {
            this.isEditMode = !this.isEditMode;
            if (!this.isEditMode) {
              this.selectedIds = [];
            }
          })
      }
      .width('100%')
      .padding(16)
      
      FavoritesList({
        isEditMode: this.isEditMode,
        selectedIds: this.selectedIds
      })
    }
  }
}

ArkTS使用@State装饰器管理编辑模式和选中状态。Blank()组件占据剩余空间,将编辑按钮推到右侧。退出编辑模式时清空选中列表,确保状态的一致性。

收藏列表组件

收藏列表展示所有收藏项,支持普通模式和编辑模式两种显示方式。

// lib/screens/favorites/widgets/favorites_list.dart
class FavoritesList extends StatelessWidget {
  final bool isEditMode;
  final Set<String> selectedIds;
  final ValueChanged<Set<String>> onSelectionChanged;

  const FavoritesList({
    super.key,
    required this.isEditMode,
    required this.selectedIds,
    required this.onSelectionChanged,
  });

  
  Widget build(BuildContext context) {
    return ListView.builder(
      padding: const EdgeInsets.all(16),
      itemCount: 10,
      itemBuilder: (context, index) {
        final id = 'item_$index';
        return FavoriteCard(
          isEditMode: isEditMode,
          isSelected: selectedIds.contains(id),
          onSelect: () {
            final newSelection = Set<String>.from(selectedIds);
            if (newSelection.contains(id)) {
              newSelection.remove(id);
            } else {
              newSelection.add(id);
            }
            onSelectionChanged(newSelection);
          },
        );
      },
    );
  }
}

列表根据编辑模式显示不同的交互元素,编辑模式下显示选择框。onSelect回调处理选择状态的切换,使用Set数据结构确保ID的唯一性。这种设计支持了批量操作的需求。

收藏卡片组件

收藏卡片展示藏品的缩略图和基本信息,编辑模式下显示选择框。

// lib/screens/favorites/widgets/favorite_card.dart
class FavoriteCard extends StatelessWidget {
  final bool isEditMode;
  final bool isSelected;
  final VoidCallback onSelect;

  const FavoriteCard({
    super.key,
    required this.isEditMode,
    required this.isSelected,
    required this.onSelect,
  });

  
  Widget build(BuildContext context) {
    return Card(
      margin: const EdgeInsets.only(bottom: 12),
      child: ListTile(
        leading: isEditMode
            ? Checkbox(value: isSelected, onChanged: (_) => onSelect())
            : ClipRRect(
                borderRadius: BorderRadius.circular(4),
                child: Image.network(
                  'https://example.com/thumb.jpg',
                  width: 56,
                  height: 56,
                  fit: BoxFit.cover,
                ),
              ),
        title: const Text('青花缠枝莲纹瓶'),
        subtitle: const Text('收藏于 2024-01-15'),
        trailing: isEditMode ? null : const Icon(Icons.chevron_right),
        onTap: isEditMode ? onSelect : () {},
      ),
    );
  }
}

卡片根据编辑模式切换leading位置的内容:普通模式显示藏品缩略图,编辑模式显示选择框。trailing位置在编辑模式下隐藏箭头图标。点击行为也根据模式不同而变化,编辑模式下点击切换选择状态。

批量操作栏

编辑模式下显示批量操作栏,提供删除和移动到分组等功能。

// lib/screens/favorites/widgets/batch_action_bar.dart
class BatchActionBar extends StatelessWidget {
  final int selectedCount;
  final VoidCallback onDelete;
  final VoidCallback onMove;

  const BatchActionBar({
    super.key,
    required this.selectedCount,
    required this.onDelete,
    required this.onMove,
  });

  
  Widget build(BuildContext context) {
    return Container(
      padding: const EdgeInsets.all(16),
      decoration: const BoxDecoration(
        color: Colors.white,
        boxShadow: [BoxShadow(color: Colors.black12, blurRadius: 4)],
      ),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        children: [
          TextButton.icon(
            icon: const Icon(Icons.delete),
            label: const Text('删除'),
            onPressed: selectedCount > 0 ? onDelete : null,
          ),
          TextButton.icon(
            icon: const Icon(Icons.folder),
            label: const Text('移动'),
            onPressed: selectedCount > 0 ? onMove : null,
          ),
        ],
      ),
    );
  }
}

批量操作栏固定在页面底部,提供删除和移动两个操作按钮。按钮在没有选中项时禁用,通过onPressed设为null实现。阴影效果使操作栏与列表内容形成视觉分离,提升层次感。

总结

本篇文章详细介绍了青花瓷App收藏夹功能的开发,包括收藏列表展示、编辑模式和批量操作。通过完善的收藏管理功能,用户可以有效地组织自己喜爱的青花瓷藏品。下一篇文章将介绍设置页面的实现。
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net

Logo

社区规范:仅讨论OpenHarmony相关问题。

更多推荐