Android 页面设计
Narrator Android 客户端 · 单 Activity + NavHostFragment · 16 个 Fragment
Narrator Android 客户端采用 单 Activity(MainActivity)+ Jetpack Navigation 架构。
所有页面均为 Fragment,通过 res/navigation/nav_graph.xml 集中声明,
由 NavController 统一调度。页面分为三类入口:
底部导航
侧边抽屉
子页面
HomeFragment,startDestination 改为 scriptFragment,
抽屉移除「主页」项。当前文档对应 docs/INDEX.md v5。
页面总览
共 16 个 Fragment(不含基类 BaseFragment),按下表分组与入口方式归类:
| # | Fragment | 文件 | 入口方式 | 参数 |
|---|---|---|---|---|
| 1 | ScriptFragment | ui/fragments/ScriptFragment.java | 底部·剧本 / 启动入口 | — |
| 2 | ScriptDetailFragment | ScriptDetailFragment.java | 点击剧本卡片 | scriptId |
| 3 | NewChapterFragment | NewChapterFragment.java | 剧本内「添加章节」 | scriptId |
| 4 | CharacterFragment | CharacterFragment.java | 底部·角色 | — |
| 5 | CharacterEditFragment | CharacterEditFragment.java | 点击系统角色 | charId |
| 6 | ScriptCharactersFragment | ScriptCharactersFragment.java | 剧本内「角色设置」 | scriptId |
| 7 | ScriptCharacterEditFragment | ScriptCharacterEditFragment.java | 点击剧本角色 | scriptId charName |
| 8 | ScriptSettingsFragment | ScriptSettingsFragment.java | 剧本内「设置」 | scriptId |
| 9 | OutlineFragment | OutlineFragment.java | 剧本内「大纲」 | scriptId |
| 10 | AiFragment | AiFragment.java | 底部·AI | — |
| 11 | AiProviderDetailFragment | AiProviderDetailFragment.java | 点击 AI 服务商 | providerId |
| 12 | DialogueFragment | DialogueFragment.java | 抽屉·对话 | — |
| 13 | DeductionFragment | DeductionFragment.java | 剧本内「演绎」 | scriptId role? |
| 14 | UiFragment | UiFragment.java | 底部·UI | — |
| 15 | TrashFragment | TrashFragment.java | 抽屉·回收站 | — |
| 16 | SettingsFragment | SettingsFragment.java | 底部·设置 | — |
| 17 | ManualFragment | ManualFragment.java | 抽屉·手册 | — |
onCreate(Bundle) 中通过 getArguments() 读取导航参数;
无参 Fragment 使用 BaseFragment.PLACEHOLDER_SCRIPT_ID(空字符串)占位。
Fragment 详情
1. ScriptFragment — 剧本列表
导航:启动入口 / 底部导航第 1 项 | 可跳转:scriptDetailFragment
从 ScriptRepository.getInstance() 取数,按分组(悬疑/科幻/奇幻等)展示剧本卡片:
状态标签(进行中 / 草稿)+ 标题 + 描述 + 分组名。点击卡片进入 ScriptDetailFragment,
底部「添加剧本」按钮调用 ScriptRepository.add(...) 后刷新列表。
2. ScriptDetailFragment — 剧本详情
导航:从剧本列表点击卡片 | 可跳转:outline / deduction / scriptCharacters / scriptSettings / newChapter
参数:scriptId(String,必填,默认 PLACEHOLDER_SCRIPT_ID)
从 ScriptRepository.getById(scriptId) 加载;标题与作者用 EditText,
通过 TextWatcher 实时回写 Repository。四个功能按钮(大纲 / 演绎 / 角色 / 设置)跳转子页面。
3. NewChapterFragment — 添加章节
入口:剧本详情点击「添加章节」 | 参数:scriptId(String)
4. CharacterFragment — 角色管理
导航:底部导航第 2 项 | 上一级:HomeFragment | 可跳转:characterEdit / scriptCharacters
双 Tab 设计:Tab「系统角色」点击跳转 CharacterEditFragment;Tab「自定义角色」展开剧本后点击跳转 ScriptCharactersFragment。
5. CharacterEditFragment — 角色详情编辑
入口:角色管理点击系统角色 | 参数:charId(String)
6. ScriptCharactersFragment — 剧本角色管理
入口:剧本详情 / 角色管理 | 参数:scriptId | 可跳转:scriptCharacterEdit
7. ScriptCharacterEditFragment — 剧本角色编辑
参数:scriptId(String)、charName(String)
8. ScriptSettingsFragment — 剧本设置
入口:剧本详情点击「设置」 | 参数:scriptId
9. OutlineFragment — 大纲编辑
入口:剧本详情点击「大纲」 | 参数:scriptId
对应 Web OutlinePage.vue。数据通过 OutlineRepository 持久化到
{filesDir}/outline/{scriptId}/outline.json(卷/章目录树)。
10. AiFragment — AI 服务商配置
导航:底部导航第 3 项 | 上一级:HomeFragment | 可跳转:aiProviderDetail
左右双面板布局:左 .left_panel 展示 AI 服务商列表(来自 AIProviderRepository → Room ai_providers 表),右 .right_panel 为配置面板占位。
11. AiProviderDetailFragment — AI 服务商详情
入口:点击 AI 服务商卡片 | 参数:providerId
编辑 AIProviderEntity 的 apiUrl / apiKey / modelName 等字段,通过 fetchModels 查询 API 支持的模型列表。
12. DialogueFragment — 对话
导航:左侧抽屉 | 对应:Web DialoguePage.vue
聚合展示跨剧本对话历史,数据来自 Room dialogues 表(DialogueEntity)。
13. DeductionFragment — 剧本推演
入口:剧本详情点击「演绎」 | 参数:scriptId(必填)、role(可选)
三栏布局:.left_panel(72dp,角色栏)+ .center_panel(weight:1,对话区)+ .right_panel(72dp,信息面板)。
演绎三阶段循环
该 Fragment 是 Narrator 的核心,实现「发言顺序链」模式(见 DeductionFragment.java):
AiService.sendChatStream(...) 自动生成。
阶段 3 · 旁白收尾:
回合结束时生成场景收尾描述,完成一轮并进入下一回合。
每个角色的完整数据(CharData)含 id、name、avatar、player(character/system)、personality、goal、relationships、abilities、temperature、status(在线/不在线/连线)。世界观描述从 OutlineRepository.load(scriptId).worldview 加载。
14. UiFragment — UI 主题配置
导航:底部导航第 4 项 | 对应:Web UiPage.vue
通过 ThemeEngine 单例管理 8 个内置色彩主题;主题数据持久化到 SharedPreferences("carrot_theme")。
页面展示主题卡片网格,点击即切换;底部展示当前主题的 16 色色板。详见 主题引擎文档。
15. TrashFragment — 回收站
导航:左侧抽屉 | 对应:Web TrashPage.vue
展示被删除的剧本列表(TrashRepository),支持恢复。删除剧本时 ScriptRepository.remove(id) 会先把剧本移入回收站。
16. SettingsFragment — 应用设置
导航:底部导航第 5 项 | 对应:Web SettingsPage.vue
含「演绎设置」与「配置管理」两个 section。默认值统一从 res/values/defaults.xml 经 util/Defaults 读取(speechMode / autoSave / engineMode / defaultModel / fontFamily / fontSize 等)。
17. ManualFragment — 使用手册
导航:左侧抽屉「手册」项 | 参数:无
应用内置使用手册页,与「对话」「回收站」同为抽屉入口的顶层页面。
代码结构
关键约束
- 页面只能通过 NavController 导航,禁止直接启动 Activity。
- 底部导航 5 个 Tab 为一级页面,切换不压栈(
popUpTo(scriptFragment, false)+launchSingleTop(true))。 - 抽屉页面同样为一级页面(对话 / 手册 / 回收站)。
- 子页面(剧本详情 / 大纲 / 演绎等)通过
navController.navigate()入栈,支持返回。 - 标题栏按钮显隐:子页面显示
←,顶层页面显示≡(由MainActivity.isSubPageDest()判定)。 - 标题栏文字自动取
NavDestination.getLabel()。 - 底部导航高亮与底部选中指示条颜色跟随当前主题,由
ThemeColorsUtil.get(...)动态应用。 - 演绎页面特殊:同时显示返回按钮与
≡菜单按钮,并隐藏底部导航及指示条。
页面变更记录
| 日期 | 版本 | 变更内容 |
|---|---|---|
| 2026-07-05 | v5 | 创建 Script 模型 + ScriptRepository(5 预置示例剧本 + CRUD);ScriptFragment 改为分组展示剧本卡片;ScriptDetailFragment 标题/作者改为 EditText + TextWatcher 实时回写。 |
| 2026-07-05 | v4 | 移除 HomeFragment 与 hero_box,startDestination 改为 scriptFragment,抽屉移除「主页」项。新增 ThemeEngine + 实装 UiFragment 6 色主题卡片网格。 |
| 2026-07-05 | v3 | 修复回退栈膨胀:navigateTo() 增加 NavOptions(launchSingleTop=true + popUpTo=scriptFragment, false)。 |
| 2026-07-05 | v2 | 新增标题栏返回按钮;scriptId 全部去硬编码为 BaseFragment.PLACEHOLDER_SCRIPT_ID;多 Fragment 修复 onCreate 参数读取;抽屉高亮同步。 |
| 2026-07-04 | v1 | 初始设计文档。 |