【安卓程序】古诗500首卡片式-墨韵诗笺 · 设计与架构篇

前言

在快节奏的数字时代,古诗词仿佛一缕清泉,润泽着浮躁的心灵。“墨韵诗笺”便是一款以水墨风格呈现的单机古诗词鉴赏应用,收录了从先秦到清代共 500 首经典诗词,旨在为用户打造一座掌上诗词桃源。它不仅提供了朝代分类浏览、卡片翻转译注、本地收藏书架等核心体验,更通过细腻的水墨视觉和流畅的交互,让古典之美在现代屏幕上复活。

本文将深入剖析“墨韵诗笺”的设计与架构,从整体蓝图到细枝末节,逐一解读技术选型背后的思考、数据流动的路径以及 UI 设计的美学逻辑,帮助开发者或技术爱好者建立起完整的认知框架。
完成后的效果如下图所示:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


第一章 项目概述与核心特性

1.1 项目定位

“墨韵诗笺”是一款纯单机离线可用的诗词鉴赏工具,支持 Web 端浏览和 Android APK 打包。它不依赖网络,所有诗词数据、收藏记录、用户偏好均存储在本地,充分保障了隐私和访问速度。

1.2 核心特性一览

  • 500 首经典诗词:六大朝代(先秦、唐、宋、元、明、清)全覆盖,含原文、白话译文、字词注释。
  • 水墨风视觉设计:宣纸米白底、青花瓷蓝与朱砂红点缀,搭配朝代徽章、3D 翻转卡片、竖排切换,沉浸感十足。
  • 虚拟滚动列表:支持 500 首规模流畅浏览,不卡顿。
  • 灵活筛选与搜索:关键词搜索、仅看收藏切换,快速定位心仪诗词。
  • 本地收藏书架:支持批量管理,数据持久化于 LocalStorage。
  • 单页应用(SPA):视图切换平滑,离线可用,可打包为 Android APK。

这些特性共同构成了一个轻量、优雅、功能完整的诗词应用,而这一切都建立在一个精心设计的系统架构之上。


第二章 系统架构总览

2.1 整体架构

“墨韵诗笺”采用经典的前后端分离(但后端极简)的架构,客户端基于 Next.js 构建,服务端仅提供静态服务或可选的轻量 API。整体架构如下图所示:

静态资源/API

服务端 可选

Next.js Standalone

Mini-Services

Caddy 反向代理

客户端 Browser / Android WebView

Next.js 16 + React 19

页面组件: 首页/列表/详情/书架

Zustand 全局状态

LocalStorage / SQLite

核心设计理念

  • 客户端为主:所有业务逻辑、数据管理、UI 渲染均在客户端完成,服务端仅作为可选的静态托管或 API 网关。
  • 构建模式双轨制:通过环境变量 BUILD_APK 控制输出模式——Web 部署使用 standalone 服务,APK 打包使用 export 静态导出。
  • 数据本地优先:诗词数据通过 JSON 文件打包进应用,收藏和偏好存储在 LocalStorage,真正实现“开箱即用”。

2.2 构建模式详解

模式BUILD_APKNext.js output适用场景
Web 服务端0 (默认)standalone部署在服务器,支持 SSR/API,适合多用户
APK 静态导出1export生成纯静态 HTML/CSS/JS,供 Capacitor 打包为 Android 应用

这样的设计使得同一套代码可以适配两种截然不同的运行环境,且无需改动业务逻辑。


第三章 技术栈选型与理由

选择合适的技术栈是项目成功的关键。“墨韵诗笺”的选型兼顾了开发效率运行性能跨端能力,具体如下:

层级技术版本选型理由
框架Next.js16.1.1支持 SSR/SSG/静态导出,灵活应对 Web 和 APK 两种模式,内置路由和优化
UI 库React19.0.0函数组件 + Hooks,生态丰富,适合构建交互密集型 SPA
语言TypeScript5.x类型安全,降低维护成本,提升代码可读性
样式Tailwind CSS4.x原子化 CSS,快速构建定制化 UI,配合 shadcn/ui 无缝协作
组件库shadcn/uilatest基于 Radix 的无头组件,提供约 50+ 高质量的 UI 基元,完全可控
状态管理Zustand5.0.6轻量、简单、无冗余,比 Redux 更易上手,适合中小型应用
动画Framer Motion12.23.2强大的声明式动画库,轻松实现页面过渡和卡片翻转等微交互
数据查询@tanstack/react-query5.82.0管理异步数据状态,缓存和重试机制完善,提升用户体验
ORMPrisma6.11.1类型安全的数据库操作,配合 SQLite,便于后续扩展用户系统
移动端打包Capacitor8.4.1将 Web 应用包装为原生 APK,保留 Web 技术栈,降低移动开发成本
包管理/运行时Bun1.3.4快速安装和运行,替代 npm/yarn,提升开发环境体验

这些技术共同构建了一个稳健、可维护的现代前端应用,而它们的整合方式将在后续章节详述。


第四章 前端架构设计

前端是用户直接交互的界面,其架构设计直接决定了应用的流畅度和可维护性。

4.1 目录结构(核心部分)

src/
├── app/                    # Next.js 路由层(实际采用单页模式)
│   ├── globals.css         # 全局水墨主题变量
│   ├── layout.tsx          # 根布局(字体、元数据)
│   └── page.tsx            # 唯一页面,渲染 AppShell
├── components/
│   ├── poetry/             # 业务组件(视图组件)
│   │   ├── app-shell.tsx   # 应用外壳(Header/Footer/视图路由)
│   │   ├── dynasty-overview.tsx  # 首页朝代画廊
│   │   ├── poetry-list.tsx       # 诗词列表(含搜索/筛选)
│   │   ├── poem-detail.tsx       # 详情页(3D 翻转卡片)
│   │   ├── bookshelf.tsx         # 收藏书架
│   │   └── virtual-list.tsx      # 虚拟滚动实现
│   └── ui/                 # shadcn/ui 基础组件(50+)
├── data/                   # 数据层
│   ├── types.ts            # Poem, Dynasty 等类型定义
│   ├── dynasties.ts        # 朝代元数据及色彩映射
│   ├── index.ts            # 数据加载器(懒加载 + 缓存)
│   └── *.json              # 各朝代诗词数据
├── store/
│   └── poetry-store.ts     # Zustand 全局状态
├── lib/                    # 工具库
│   ├── storage.ts          # LocalStorage 服务(防抖持久化)
│   └── poem-utils.ts       # 诗词处理函数
└── hooks/                  # 自定义 Hooks

这种结构清晰地将视图数据状态工具分离,使得各模块职责单一,便于测试和协作。

4.2 视图系统与路由逻辑

应用采用单页四视图架构,通过 Zustand 中的 view 状态控制当前显示的组件,并利用 Framer Motion 的 AnimatePresence 实现平滑切换。

视图view组件功能
首页"home"DynastyOverview展示朝代徽章、总数统计、快捷入口
列表"list"PoetryList朝代 Tab 切换、搜索、虚拟滚动列表
详情"detail"PoemDetail全屏覆盖层,3D 翻转卡片,字体/竖排调节
书架"bookshelf"Bookshelf收藏网格展示,批量管理,搜索

路由逻辑(位于 app-shell.tsx)简洁明了:

home

list

detail

bookshelf

当前 view 值?

DynastyOverview

PoetryList

PoemDetail 覆盖层

Bookshelf

4.3 组件树分解

为了更直观地理解页面层级,我们可以将 AppShell 下的组件树绘制如下:

AppShell

Header

Main

Footer

Logo (墨韵诗笺+印章)

Nav (首页/书架+收藏徽章)

DynastyOverview

PoetryList

PoemDetail (覆盖层)

Bookshelf

Banner

DynastyCard ×6

QuickEntry

DynastyTabs

SearchBar + 仅看收藏

VirtualList

PoemRow

Toolbar (收起/上下首/竖排/字号/收藏)

FlipCard

正面: 原文

背面: 译文+注释

标题+批量管理

BookshelfSearch

收藏卡片网格

该组件树清晰地展示了各视图的构成,保证了代码的组织性和可读性。

4.4 状态管理——Zustand 的巧妙运用

Zustand 作为全局状态管家,承担了应用所有可变数据的存储和更新。其核心状态结构如下:

interface PoetryState {
  // 导航
  view: 'home' | 'list' | 'detail' | 'bookshelf';
  currentDynasty: Dynasty;
  
  // 数据 (惰性加载)
  lists: Record<Dynasty, Poem[]>;
  loadingDynasty: Dynasty | null;
  
  // 详情
  currentPoemId: string | null;
  detailList: Poem[];  // 当前详情页所在的列表,用于上下首切换
  
  // 收藏
  favorites: string[]; // 收藏的 poem id 数组
  
  // 筛选
  searchQuery: string;
  onlyFavorites: boolean;
  
  // UI 偏好
  fontScale: number;
  listScrollTop: number;
  
  // 动作 (Actions)
  goHome: () => void;
  goBookshelf: () => void;
  openDynasty: (dynasty: Dynasty) => void;
  switchDynasty: (dynasty: Dynasty) => void;
  openDetail: (id: string, list: Poem[]) => void;
  closeDetail: () => void;
  nextPoem: () => void;
  prevPoem: () => void;
  toggleFavorite: (id: string) => void;
  removeFavorites: (ids: string[]) => void;
  setSearchQuery: (q: string) => void;
  setOnlyFavorites: (v: boolean) => void;
  adjustFontScale: (delta: number) => void;
  hydrate: () => void; // 从 localStorage 恢复状态
}

关键设计思考

  • 收藏写入防抖toggleFavorite 触发后,并不会立即写入 LocalStorage,而是通过一个 300ms 防抖函数批量写入,避免频繁 I/O 影响性能。
  • 页面卸载强制刷新:在 hydrate 中注册 beforeunloadpagehide 事件,确保浏览器关闭或刷新时收藏数据已落盘。
  • 列表滚动位置记忆listScrollTop 用于在返回列表时恢复滚动位置,提升浏览连续性。

Zustand 的 selector 模式 也被广泛使用,组件仅订阅自己关心的状态片段,从而避免不必要的重新渲染。


第五章 数据架构与加载策略

5.1 数据模型

诗词数据是应用的核心资产,其模型定义如下:

interface Poem {
  id: string;               // 如 "T001" (T=唐)
  title: string;
  author: string;
  dynasty: Dynasty;         // "唐" | "宋" | ...
  content: string;          // 原文,\n 分隔
  translation: string;      // 白话译文
  annotation?: string;      // 字词注释
  background_hint?: string; // 意境提示,用于背景色
  sort_order?: number;      // 按作者生卒年排序
}

type Dynasty = "唐" | "宋" | "元" | "明" | "清" | "先秦";

每个朝代均独立存储为一个 JSON 文件,文件命名与朝代对应,例如 tang.json 存放唐诗,song.json 存放宋词等。

5.2 存储策略矩阵

数据类别存储介质容量估算写入时机
诗词正文JSON 文件(打包进应用)~300KB(6 个文件)编译时打包,运行时只读
收藏列表LocalStorage (poetry_favorites)~5KB防抖 300ms,页面卸载时强制刷新
字号偏好LocalStorage (poetry_font_scale)~10B用户调节时立即写入
上次浏览朝代LocalStorage (poetry_last_dynasty)~10B切换朝代时记录
用户扩展数据SQLite(db/custom.db,通过 Prisma)可变预留未来扩展

5.3 数据加载流程——按需懒加载

为避免首屏加载全部 500 首诗词,我们设计了按朝代懒加载机制,其流程如下:

内存缓存Data LoaderZustand StoreUIUser内存缓存Data LoaderZustand StoreUIUseralt[缓存存在][缓存不存在]点击 "唐诗" 朝代调用 openDynasty("唐")loadDynasty("唐")检查是否有 "唐" 的数据返回 Poem[]import("./tang.json")按 sort_order 排序存入缓存返回 Poem[]更新 lists["唐"]触发重新渲染显示唐诗列表

设计亮点

  • Dynamic Import:仅在需要时加载对应朝代的 JSON,降低首屏资源下载量。
  • 内存缓存:加载一次后即存入 Map,后续访问无需重复请求。
  • 排序预处理:JSON 文件中原有的 sort_order 保证列表按作者生卒年排列,无需前端再计算。

5.4 数据集概览

朝代文件数量ID 范围文件大小(约)
tang.json180 首T001–T1801,982 行
song.json155 首S001–S1551,707 行
yuan.json35 首Y001–Y035387 行
ming.json50 首M001–M050551 行
qing.json50 首C001–C050551 行
先秦pre-qin-han.json30 首Q001–Q030332 行
合计500 首~5,510 行

其中特别收录了《滕王阁序》《长恨歌》《琵琶行》等长篇名作,原文完整无删减。


第六章 UI 设计系统——水墨意境的数字表达

设计系统不仅是视觉规范,更是品牌情绪的传递。“墨韵诗笺”以水墨丹青为核心意象,将传统美学融入现代界面。

6.1 主题色彩

角色色值文化意象
背景#f4ecdb宣纸米白,温润质朴
前景#2b2620墨黑,沉稳内敛
主色#1f4e66青花瓷蓝,雅致端庄
强调色#b9493b朱砂红,点睛之笔
次要背景#e8dcc4浅宣纸,层次过渡
边框#d8cab0淡墨线,柔和勾勒

6.2 朝代专属配色——情绪化表达

每个朝代都有其独特的文化气质,我们通过配色渐变予以视觉暗示:

朝代主题色渐变方向情绪基调
先秦#5a4a78古朴神秘悠远苍茫
#1f4e66 青花蓝大气开阔盛世风华
#7a5e2e 赭色素雅内敛文人风骨
#4a6a5a 青绿旷达疏朗洒脱不羁
#8a4035 朱赭沉郁厚重复古典雅
#34506a 墨青清冷深邃含蓄隽永

6.3 情绪色彩映射——让背景“说话”

详情页的卡片背景会根据诗词的 background_hint 字段匹配 15 种预设意境色,例如:

  • spring → 春意盎然的 #6a8a5a
  • night → 暗夜沉静的 #1a1f2e
  • war → 苍凉悲壮的 #5a3a3a

这一细节极大增强了阅读的沉浸感。

6.4 字体与工具类

  • 字体
    • 正文:Noto Serif SC(衬线宋体,适合长文阅读)
    • 标题:Ma Shan Zheng(毛笔行书,彰显水墨气质)
    • UI:Geist(系统无衬线,现代简洁)
  • 自定义 CSS 工具类(节选):
    • .paper-bg:宣纸纹理(多层纤维 + 墨晕)
    • .flip-card:3D 翻转容器
    • .vertical-rl:竖排文字(writing-mode: vertical-rl
    • .heart-pop:收藏按钮的心跳动画

这些工具类共同构建了“墨韵诗笺”独一无二的视觉语言。


第七章 小结

通过本章,我们系统了解了“墨韵诗笺”的设计与架构——从项目愿景到技术选型,从组件树到数据流,从配色方案到情绪映射。每一处设计都秉持着简洁、优雅、离线优先的原则,旨在为用户提供纯粹的古诗词欣赏体验。

在下一篇文章中,将深入探讨部署、构建、性能优化与运维细节,帮助您将这套架构真正落地运行。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

海兰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值