请添加图片描述

读书笔记是阅读的重要产出,好的笔记能帮助我们更好地理解和记忆书中的内容。笔记列表页面展示用户的所有读书笔记,支持按书籍筛选、搜索等功能。

做这个页面的时候,我参考了一些笔记类App的设计,它们都很注重内容的展示和快速浏览。

依赖引入

import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import '../../app/routes/app_routes.dart';

标准的依赖引入,app_routes 用于页面跳转。

页面主体结构

class NoteListPage extends StatelessWidget {
  const NoteListPage({super.key});

  
  Widget build(BuildContext context) {
    final notes = [
      {'book': '百年孤独', 'content': '孤独是人类永恒的主题,马尔克斯用魔幻现实主义的手法,展现了布恩迪亚家族七代人的命运...', 'date': '2024-01-15', 'page': '第285页'},
      {'book': '百年孤独', 'content': '奥雷里亚诺上校发动了32次战争,全部失败。这种宿命般的孤独感贯穿整个家族。', 'date': '2024-01-14', 'page': '第240页'},
      {'book': '人类简史', 'content': '认知革命让智人能够讨论虚构的事物,这是人类区别于其他动物的关键能力。', 'date': '2024-01-13', 'page': '第56页'},
      {'book': '三体', 'content': '黑暗森林法则:宇宙就是一座黑暗森林,每个文明都是带枪的猎人。', 'date': '2024-01-10', 'page': '第320页'},
      {'book': '活着', 'content': '人是为活着本身而活着,而不是为了活着之外的任何事物所活着。', 'date': '2024-01-08', 'page': '第180页'},
    ];

笔记数据暂时写死,实际项目中应该从数据库读取。每条笔记包含书名、内容、日期、页码四个字段。

Scaffold 结构

    return Scaffold(
      backgroundColor: const Color(0xFFFDF8F3),
      appBar: AppBar(
        title: const Text('读书笔记'),
        backgroundColor: const Color(0xFF5B4636),
        foregroundColor: Colors.white,
        actions: [
          IconButton(icon: const Icon(Icons.filter_list), onPressed: () {}),
          IconButton(
            icon: const Icon(Icons.search),
            onPressed: () => Get.toNamed(AppRoutes.search),
          ),
        ],
      ),

AppBar 右上角有筛选和搜索两个按钮。筛选可以按书籍、日期等条件过滤笔记,搜索可以全文检索。

列表渲染

      body: ListView.builder(
        padding: EdgeInsets.all(16.w),
        itemCount: notes.length,
        itemBuilder: (context, index) => _buildNoteCard(notes[index]),
      ),

ListView.builder 渲染笔记列表,比直接用 Column 性能更好,因为它只渲染可见的项。

悬浮添加按钮

      floatingActionButton: FloatingActionButton(
        backgroundColor: const Color(0xFF5B4636),
        onPressed: () => Get.toNamed(AppRoutes.addNote),
        child: const Icon(Icons.add, color: Colors.white),
      ),
    );
  }

悬浮按钮用于添加新笔记,点击跳转到添加笔记页面。

笔记卡片组件

  Widget _buildNoteCard(Map<String, String> note) {
    return GestureDetector(
      onTap: () => Get.toNamed(AppRoutes.noteDetail),
      child: Container(
        margin: EdgeInsets.only(bottom: 12.h),
        padding: EdgeInsets.all(16.w),
        decoration: BoxDecoration(
          color: Colors.white,
          borderRadius: BorderRadius.circular(12.r),
        ),

每条笔记是一个白色卡片,点击跳转到笔记详情页面。卡片之间留 12 的间距。

卡片头部信息

        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Row(
              children: [
                Container(
                  padding: EdgeInsets.symmetric(horizontal: 10.w, vertical: 4.h),
                  decoration: BoxDecoration(
                    color: const Color(0xFF5B4636).withOpacity(0.1),
                    borderRadius: BorderRadius.circular(4.r),
                  ),
                  child: Text(
                    note['book']!,
                    style: TextStyle(
                      fontSize: 12.sp,
                      color: const Color(0xFF5B4636),
                      fontWeight: FontWeight.w500,
                    ),
                  ),
                ),

头部左边是书名标签,用浅棕色背景突出显示。这样用户一眼就能看出这条笔记是哪本书的。

页码和日期

                SizedBox(width: 8.w),
                Text(
                  note['page']!,
                  style: TextStyle(
                    color: Colors.grey[500],
                    fontSize: 11.sp,
                  ),
                ),
                const Spacer(),
                Text(
                  note['date']!,
                  style: TextStyle(
                    color: Colors.grey[500],
                    fontSize: 11.sp,
                  ),
                ),
              ],
            ),

页码在书名旁边,日期在最右边。这些是次要信息,用灰色小字显示。

笔记内容

            SizedBox(height: 12.h),
            Text(
              note['content']!,
              style: TextStyle(
                fontSize: 14.sp,
                color: Colors.grey[800],
                height: 1.5,
              ),
              maxLines: 3,
              overflow: TextOverflow.ellipsis,
            ),

笔记内容是卡片的主体,最多显示 3 行,超出部分用省略号。行高设为 1.5,让文字更易读。

底部操作栏

            SizedBox(height: 12.h),
            Row(
              children: [
                Icon(Icons.favorite_border, size: 18.sp, color: Colors.grey[400]),
                SizedBox(width: 4.w),
                Text('12', style: TextStyle(color: Colors.grey[500], fontSize: 12.sp)),
                SizedBox(width: 16.w),
                Icon(Icons.share, size: 18.sp, color: Colors.grey[400]),
              ],
            ),
          ],
        ),
      ),
    );
  }
}

底部有收藏和分享两个操作。收藏旁边显示收藏数,让用户知道这条笔记有多少人喜欢。

列表性能优化

ListView.builder 相比 ListView 有几个优势:

懒加载:只渲染可见区域的项,节省内存。

复用:滚动时复用已有的 Widget,减少创建开销。

流畅:大量数据时滚动更流畅。

筛选功能设计

筛选功能可以按以下维度过滤:

按书籍:只显示某本书的笔记。

按日期:显示某个时间段的笔记。

按类型:摘录、感想、问题等不同类型。

按标签:用户自定义的标签。

搜索功能设计

搜索功能应该支持:

全文搜索:在笔记内容中搜索关键词。

书名搜索:搜索某本书的所有笔记。

高亮显示:搜索结果中高亮匹配的关键词。

空状态处理

如果用户还没有任何笔记,应该显示一个空状态页面,引导用户添加第一条笔记。可以放一个插图和一段鼓励的文字。

小结

笔记列表页面用卡片形式展示所有读书笔记,每张卡片包含书名、页码、日期、内容摘要和操作按钮。ListView.builder 保证了列表的性能。

筛选和搜索功能帮助用户快速找到想要的笔记,悬浮按钮方便添加新笔记。

下一篇会讲添加笔记页面的实现,让用户可以记录自己的读书感想。


欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐