- 移动开发
- 前端
- UI组件
【免费下载链接】kittenTricks
React Native starter kit with over 40 screens and modern Light and Dark theme for creating stunning cross-platform mobile applications.
导读
本文以仓库根目录下的 CHANGELOG.md 为主体骨架,围绕 Kitten Tricks 自 v2.0.1 至 v2.4.0 的版本演进记录,逐一拆解其背后的技术变更:UI Kitten / Eva Design System 升级、React Navigation v5 迁移、函数组件与 Hooks 重写、React Native 与 Expo 双环境可运行,以及系统外观(深色模式)联动切换主题等关键能力。通过对源码实现(src/app、src/services、src/scenes/themes、src/navigation等目录)的佐证分析,你将清晰掌握这套“40+ 屏跨平台 UI 模板”的架构脉络、主题/映射运行机制与版本升级路径,为复用它搭建自己的跨平台应用提供可验证的参考。
版本总览:一条持续演进的升级路线
CHANGELOG.md 记录的版本时间线如下:
| 版本 | 发布时间 | 核心内容 |
|---|---|---|
| 2.4.0 | 2020-02-10 | 升级 UI Kitten v4.4.0、Eva Material 兼容、React Navigation v5、RN/Expo 双环境可运行 |
| 2.4.0-beta.3 | 2020-01-22 | UI Kitten v4.4.0-beta.3;修复“系统外观联动主题切换” |
| 2.4.0-beta.2 | 2020-01-16 | 函数组件 + Hooks 重写、结构重构、Expo SDK 36 |
| 2.0.1 | 2019-06-20 | 大规模框架适配重构、主题变量重构、本地化资源、Eva 适配 |
其中 2.4.0-beta.2 是一次里程碑式重构:Rewrite with functional components and React hooks,并为“更易于复用屏幕”而升级应用结构;紧随其后的 2.4.0-beta.3 修复了系统外观(深色模式)与主题联动的关键 bug;最终 2.4.0 正式版把这些能力收敛为“Eva material compatibility”“Upgrade React Navigation to v5”与“Make runnable in both React Native and Expo environments”三大特性。
从 package.json 可确认当前仓库停留在 2.4.0:依赖@ui-kitten/components@5.1.0、react-navigation系列全部为 v5、react-native@~0.63.4、expo@^40.0.0。可见 CHANGELOG 与代码库状态是严格对齐的。
核心特性一:UI Kitten 与 Eva Design System 的版本共振
从 v4.4.0 到 v5.1.0 的依赖升级
CHANGELOG 中反复出现 “Upgrade UI Kitten to v4.4.0(-beta.x)” 的字样。UI Kitten 是 Kitten Tricks 的 UI 组件库基础,Eva Design System 则提供可扩展的设计 token 与映射(mapping)。二者在本仓库中的最终落地依赖为(见 package.json):
"@ui-kitten/components": "5.1.0", "@ui-kitten/date-fns": "5.1.0", "@ui-kitten/eva-icons": "5.1.0", "@ui-kitten/moment": "5.1.0", "@eva-design/eva": "^2.1.0", "@eva-design/material": "^2.1.0"mapping:设计语言如何被“映射”为组件样式
“Eva material compatibility”这一特性在源码中体现为Mapping类型——它决定了应用采用哪套设计规范(见 theme.service.ts):
export type Mapping = 'eva' | 'material';应用启动时,app-theming.ts将两套 mapping 与自定义覆盖层合并注入:
export const appMappings = { eva: { mapping: eva.mapping, customMapping: customEva, // app-mapping-eva.json }, material: { mapping: material.mapping, customMapping: customMaterial, // app-mapping-material.json }, };其中 app-mapping-eva.json 以opensans-regular为全局字体,并为TopNavigation、StatusBar等组件声明了外观与变体元数据;而 app-mapping-material.json 则把字体切换为roboto-regular,并让StatusBar使用light-content样式与color-primary-700背景。两套 mapping 的差异正好对应 CHANGELOG 中“Eva material compatibility”这项特性——同一套组件代码,通过 mapping 就能整体切换设计语言。
品牌主题:自定义品牌色的注入方式
除了 eva/material 内置主题,Kitten Tricks 还支持brand主题(见 app-theming.ts):
brand: { light: appTheme, dark: appTheme, }app-theme.json 定义了 10 级品牌色阶(color-primary-100到color-primary-900)以及 6 级透明色(color-primary-transparent-100到-600),主色为#FF6721。这套色阶在主题卡片中被实际渲染(见下文《主题切换的实现链路》)。
核心特性二:React Navigation v5 迁移与导航结构
从旧版到 v5 的迁移
CHANGELOG 分别在 beta.2 与正式版中两次提到 “Upgrade React Navigation to v5”。当前 package.json 中的导航依赖全部为 v5:
"@react-navigation/native": "^5.9.2", "@react-navigation/stack": "^5.14.2", "@react-navigation/bottom-tabs": "^5.11.7", "@react-navigation/drawer": "^5.12.3", "@react-navigation/material-top-tabs": "^5.3.13"三层导航结构与运行时换肤衔接
入口 app.navigator.tsx 使用NavigationContainer包裹,并将背景色设为transparent以“防止导航时布局闪烁”——这是保证主题运行时切换无感的重要细节:
const navigatorTheme = { ...DefaultTheme, colors: { ...DefaultTheme.colors, background: 'transparent' }, };再往下一层,home.navigator.tsx 展示了 v5 的组合式 API:外层Drawer.Navigator(Home 与 Libraries 两个入口),内层BottomTab.Navigator(Layouts / Components / Themes 三个 Tab),并通过TabBarVisibilityOptions依据route.state?.index控制嵌套路由下 Tab 栏的显隐。注意initialTabRoute的取值逻辑:__DEV__环境下默认打开 Components,生产环境默认打开 Layouts。
AppNavigator (NavigationContainer) └── HomeNavigator (Drawer) ├── Home (BottomTabs) │ ├── Layouts → LayoutsNavigator (Stack) │ ├── Components→ ComponentsNavigator (Stack) │ └── Themes → ThemesNavigator (Stack) └── Libraries导航主题与 App 主题解耦
导航层使用@react-navigation/native提供的DefaultTheme,而 UI 层由ApplicationProvider注入 UI Kitten 主题(见 app.component.tsx)。两者互相独立,这正是“主题在运行时直接切换、无需重载应用”能够成立的前提之一。
核心特性三:函数组件与 React Hooks 重写
beta.2 的架构性变更
CHANGELOG 记录 beta.2 完成 “Rewrite with functional components and React hooks” 与 “Upgrade application structure for easier screens reusage”。这在当前源码中随处可见:
- app.component.tsx:
App与Splash均为函数组件,通过useMapping/useTheming两个自定义 Hook 管理映射与主题; - theme.service.ts:
Theming.useMapping、Theming.useTheming、Theming.useTheme三个静态方法本质上是基于React.useState/React.useEffect/React.useContext封装的主题 Hook 工厂; - themes.component.tsx:主题切换页完全由
useState/useContext驱动; - app-loading.component.rn.tsx 与 app-loading.component.expo.tsx:两套加载器都是函数组件 + Hooks 的实现。
Hook 化的主题上下文
theme.service.ts 中定义了两个 Context:
export interface MappingContextValue { currentMapping: Mapping; setCurrentMapping: (mapping: Mapping) => void; isEva: () => boolean; } export interface ThemeContextValue { currentTheme: Theme; setCurrentTheme: (theme: Theme) => void; isDarkMode: () => boolean; createTheme: (upstreamTheme: Theme) => any; }useTheming内部通过React.useState持有当前主题,并通过Appearance.addChangeListener订阅系统外观变化(详见下一节),卸载时移除订阅:
React.useEffect(() => { const subscription = Appearance.addChangeListener((preferences) => { setCurrentTheme(Theming.createAppearanceTheme(preferences.colorScheme, theme)); }); return () => subscription.remove(); }, []);这正是 2.4.0-beta.3 所修复的“Theme switch using system appearance”的最终形态——CHANGELOG 中的 bug fix 条目(8eabc16)在源码里落地为这段订阅逻辑。
核心特性四:React Native 与 Expo 双环境可运行
.expo 后缀的双实现模式
“Make runnable in both React Native and Expo environments”是 2.4.0 正式版最亮眼的特性。仓库对此采用了一套清晰的实现约定:同一逻辑提供两份实现,一份以.expo.ts(x)为后缀,另一份为普通文件,运行时依据Constants.platform选择(这与 Expo 官方的.expo扩展名模式一致,详见 DEV_DOCS.md 的说明)。
典型示例:
- app-loading.component.tsx:根据
Constants.platform在 Expo 与 RN 两个加载实现间二选一; - app-reload.service.ts:同理分发到 app-reload.service.expo.ts(
Updates.reload())或 app-reload.service.rn.ts(NativeModules.DevMenu.reload()); - 另有 app-info.service.ts、web-browser.service.ts 等遵循同一模式。
两套启动加载器的差异
app-loading.component.rn.tsx 中,LoadFontsTask/LoadAssetsTask直接打印“纯 RN 项目无需此任务,请使用react-native.config.js”的警告并返回null;而 app-loading.component.expo.tsx 则真正调用Font.loadAsync与Asset.fromModule(...).downloadAsync()完成字体与资源预加载,并在任务完成后调用SplashScreen.hideAsync()隐藏启动屏。
加载任务的编排入口在 app.component.tsx:
const loadingTasks: Task[] = [ () => LoadFontsTask({ 'opensans-regular': require('../assets/fonts/opensans-regular.ttf'), 'roboto-regular': require('../assets/fonts/roboto-regular.ttf'), }), () => AppStorage.getMapping(defaultConfig.mapping).then(result => ['mapping', result]), () => AppStorage.getTheme(defaultConfig.theme).then(result => ['theme', result]), ];即:启动时预加载字体,并从 AsyncStorage 读取用户上次选择的 mapping 与 theme(不存在则回退到默认值{ mapping: 'eva', theme: 'light' })。AppLoading组件在任务全部完成后才渲染真正的App(见 app-loading.component.rn.tsx 的startTasks与Promise.all逻辑)。
双环境运行方式
根据 DEV_DOCS.md,两种运行方式均受支持:
- 纯 React Native 方式:
yarn start启动 Metro,yarn ios/yarn android运行到设备; - Expo 方式:根目录执行
expo start,可输出 iOS / Android / Web 三种运行目标;此时ios、android目录并非必需。
主题切换的实现链路:从 CHANGELOG bug 到完整闭环
切换入口:Themes 页面
2.4.0-beta.3 修复的“Theme switch using system appearance”在 themes.component.tsx 中构成完整闭环。该页面通过Theming.MappingContext/Theming.ThemeContext读取当前映射与主题:
- 列表中的每个
ThemeItem由ThemesService.createThemeListItems生成(见 themes.service.ts),过滤掉brand后按eva light / eva dark / material light / material dark依次排列; - 点击卡片调用
themeContext.setCurrentTheme(item.name),即setCurrentTheme→AppStorage.setTheme(nextTheme)→setCurrentTheme(nextTheme)(见 theme.service.ts 与 app-storage.service.ts); - 主题被写入 AsyncStorage 并持久化,下次启动由
AppStorage.getTheme恢复。
主题卡片与品牌色渲染
theme-card.component.tsx 使用 UI Kitten 的StyleService.create定义主题化样式,卡片正文渲染六个色块,其背景依次取background-basic-color-2/3、background-alternative-color-1/2、text-basic-color与color-primary-default——这些 token 值正是随当前主题动态变化的,因此卡片本身就能直观预览主题色板。
设计系统(mapping)切换:需要重启
与主题切换不同,mapping 切换需要重启应用。themes.component.tsx 中的 Toggle(Eva Design System)切换时执行mappingContext.setCurrentMapping(...)并弹出RestartAppModal:
- app-storage.service.ts 将 mapping 持久化到 AsyncStorage;
- restart-app-modal.component.tsx 提示用户 “Please restart the application for switching Design System”;
useMapping注释明确说明:“Currently, there is no way to switch during the run time, so the Async Storage and Expo Updates is used”(见 theme.service.ts)。
这也是 CHANGELOG 中“Eva material compatibility”与“双环境可运行”两项特性的交汇点:Expo 环境下重启通过Updates.reload(),纯 RN 环境下通过NativeModules.DevMenu.reload(),二者由 app-reload.service.ts 统一分发。
系统外观联动:运行时动态换肤的关键
createAppearanceTheme的判定逻辑(见 theme.service.ts):
private static createAppearanceTheme = (appearance: ColorSchemeName, preferredTheme: Theme): Theme => { if (appearance === 'no-preference') { return preferredTheme; } return appearance; };当设备外观变为 dark/light 时,监听器将当前主题同步切换为对应值;仅当系统无偏好时才回退到用户上次选择。配合 README 声称的 “themes can be changed in the runtime, without any need of reloading the application” 以及导航层transparent背景(防止切换瞬间闪烁),这就是 2.4.0-beta.3 修复后开箱即用的运行效果。
早期版本回顾:2.0.1 与 v2.0.0 时代的积累
CHANGELOG 后半段记录了 2.0.1 及更早的大量提交,可归纳为几条主线:
- Eva / UI Kitten 体系对齐:
refactor(package): adopt to eva (#144)、refactor(theme): theme variables refactor、build(common): setup app to watch framework and eva changes等,把应用逐步迁移到 Eva Design System 的 token 化主题体系; - 屏幕与布局建设:
feat(auth): auth layouts、feat(layout): articles & feed、feat(messaging): chats add、feat(e-commerce): e-commerce screens add (#99)、feat(trainings): trainings layout add (#94)、feat(dashboard): add dashboard layouts、feat(theme): theme switch feature add等——这些正是 src/layouts 下 auth/social/articles/messaging/dashboards/ecommerce 六大分类的来源; - 双端适配细节:
fix(app): android status bar fix、fix(theme): fix invisible status bar on android when dark theme is used、fix(layout): add keyboard-avoiding behavior、fix(common): lock app for portrait orientation等,处理 Android 状态栏、键盘避让与方向锁定等真实落地问题; - 工程化:
feat(common): make Kitten Tricks an Expo app、build(common): add prod/dev build configurations、fix(script): first-time start、docs(dev): add DEV_DOCS.md,奠定了 package.json 中env脚本(node ./env/set-env.js)与start/start:dev双环境启动模式的基础。
注:该段所列 commit 信息均直接来源于 CHANGELOG.md,涉及的部分 refactor/fix 对应实现可在 src/scenes 与 src/layouts 中按目录名检索对应文件进一步核对。
版本工程的实践启示
回顾整个 CHANGELOG,可以提炼出三条可复用的工程经验:
- 依赖升级与框架迁移要小步快跑:UI Kitten 从 v4.4.0-beta 系列到正式版、React Navigation 从 v4 到 v5,都是通过 beta 版本逐批推进的,每个阶段都有独立修复(如系统外观切换 bug)后再合入正式版;
- 双实现模式(
.expo.tsx+ 普通文件)是“一套代码跑两个环境”的务实方案:仅在平台能力有差异的薄服务层(reload、app-info、web-browser)做分流,业务页面保持单一实现; - 持久化与运行时状态分离:主题选择先写入 AsyncStorage(启动时恢复),运行时再通过
Appearance监听叠加系统外观,形成“用户偏好 + 系统偏好”的优先级模型。
若要在自己的项目中复现这套架构,可直接复用 app-theming.ts、theme.service.ts、app-storage.service.ts 三个文件的模式,并结合 DEV_DOCS.md 中关于环境切换(yarn env prod/yarn env dev)与屏幕复用(拷贝 src/layouts 下整目录并补齐 3rd-party.ts 所列第三方模块)的说明进行集成。
相关文件索引
- 版本记录:CHANGELOG.md
- 依赖清单:package.json
- 应用入口与启动任务:app.component.tsx、app-loading.component.tsx、app-loading.component.expo.tsx、app-loading.component.rn.tsx
- 主题与映射:app-theming.ts、app-theme.json、app-mapping-eva.json、app-mapping-material.json
- 主题服务与持久化:theme.service.ts、app-storage.service.ts、app-reload.service.ts
- 主题切换页面:themes.component.tsx、theme-card.component.tsx、themes.service.ts、restart-app-modal.component.tsx
- 导航结构:app.navigator.tsx、home.navigator.tsx
- 开发文档:DEV_DOCS.md
- 移动开发
- 前端
- UI组件
【免费下载链接】kittenTricks
React Native starter kit with over 40 screens and modern Light and Dark theme for creating stunning cross-platform mobile applications.
相关推荐
Jina Reader 完整指南:三步把网页变成 LLM 能读的 Markdown
Jina Reader 完整指南:三步把网页变成 LLM 能读的 Markdown Jina Reader 是一个开源的 URL 转 Markdown 转换服务
后端AI 应用网页爬虫搜索引擎typeahead.js 版本演进全解析:从 CHANGELOG 读懂 0.8.0 到 0.11.1 的架构变革与升级要点
typeahead.js 版本演进全解析:从 CHANGELOG 读懂 0.8.0 到 0.11.1 的架构变革与升级要点 typeahead.js 是一个快速
前端UI组件Traefik 版本演进全解读:从 CHANGELOG 看 v1.0 到 v3.7 的架构变迁与升级要点
Traefik 版本演进全解读:从 CHANGELOG 看 v1.0 到 v3.7 的架构变迁与升级要点 导读 :Traefik 的 CHANGELOG.md
后端API网关负载均衡微服务网络云原生
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考