You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Flutter Staggered Grid View中实现类Google Keep的钉选笔记置顶分组

基于staggered_grid_view实现Google Keep风格钉选笔记方案

前置适配

  • 笔记数据库层已经完成pinned布尔字段扩展,查询笔记列表时直接按pinned DESC, 更新时间 DESC排序拉取,返回结果天然是钉选笔记在前、普通笔记在后,省去客户端二次排序的性能开销
  • 推荐使用flutter_staggered_grid_view: ^0.7.0及以上版本,该版本原生支持嵌套Sliver组件构建分区分组,无需手动计算网格偏移量

核心组件搭建逻辑

不要直接用单实例StaggeredGridView.count装载全量笔记,将整个页面视图替换为CustomScrollView结构,把分组标题、网格内容拆分为独立Sliver组件依次拼接,从根源上实现分组边界可控

  • 第一步:封装可复用的笔记网格生成方法,传入对应分组的笔记列表,返回适配的SliverMasonryGrid组件:
    SliverMasonryGrid(
      gridDelegate: const SliverSimpleGridDelegateWithFixedCrossAxisCount(
        crossAxisCount: 2, // 保持Google Keep同款双列交错布局
      ),
      delegate: SliverChildBuilderDelegate(
        (context, index) {
          final currentNote = groupNoteList[index];
          return NoteCard(note: currentNote); // 复用现有开发完成的笔记卡片组件
        },
        childCount: groupNoteList.length,
      ),
    )
    
  • 第二步:通过SliverMainAxisGroup把每个分组的标题、对应网格内容绑定为独立区块,按顺序排布两个分组区块:
    CustomScrollView(
      slivers: [
        // 钉选笔记分组区块
        SliverMainAxisGroup(
          slivers: [
            // pinned分组标题
            SliverPadding(
              padding: const EdgeInsets.fromLTRB(16, 24, 16, 8),
              sliver: SliverToBoxAdapter(
                child: Text(
                  'pinned',
                  style: Theme.of(context).textTheme.titleSmall,
                ),
              ),
            ),
            // 钉选笔记网格,无内容时返回空占位
            if (pinnedNoteList.isNotEmpty) buildNoteGrid(pinnedNoteList),
          ],
        ),
        // 普通笔记分组区块
        SliverMainAxisGroup(
          slivers: [
            // others分组标题,加足上下间距做区域视觉区分
            SliverPadding(
              padding: const EdgeInsets.fromLTRB(16, 32, 16, 8),
              sliver: SliverToBoxAdapter(
                child: Text(
                  'others',
                  style: Theme.of(context).textTheme.titleSmall,
                ),
              ),
            ),
            // 普通笔记网格
            buildNoteGrid(otherNoteList),
          ],
        )
      ],
    )
    
  • 第三步:细节优化还原Google Keep效果:
    • 两个分组区块之间预留足够的垂直内边距,也可以在普通笔记标题上方加一根1px高度、低透明度的分割线,强化区域区分感
    • 钉选状态变更时,仅需要在本地分组数组中移动对应笔记条目(从普通组移除、插入钉选组最前,或反向操作),触发组件刷新即可,无需对全量列表做重排计算

避坑提醒

  • 不要使用低版本StaggeredGridView的全量列表模式硬塞分组标题,这种模式下标题会被识别为网格单个条目,无法跨列铺满,必然出现布局错位
  • 当对应分组没有笔记时,直接隐藏对应分组的标题,和Google Keep的交互逻辑保持一致
  • 分组内的笔记卡片高度差异可以完全保留原有实现,SliverMasonryGrid会自动完成列方向的对齐,不需要手动调整每个卡片的网格高度占比

内容的提问来源于stack exchange,提问作者Babsky

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.23 21:06:07