我们又来啦 又又上架了一个鸿蒙项目-萤火故事屋
萤火故事屋介绍

萤火故事屋 是青蓝逐码孵化的一款针对儿童类的鸿蒙元服务,打造全龄段语言娱乐空间,涵盖童话、脑筋急转弯、绕口令、猜谜语四大模块。童话配立生动剧情,脑筋急转弯、谜语设阶梯模式,绕口令丰富多彩。即刻开启思维与语言的趣味之旅!

萤火故事屋从 4 月 1 号立项,开发时间一个月,预计 5 月 1 号上架。

但是一开始萤火故事屋的名字是叫做 故事大王 ,因为故事大王这个名字起初在鸿蒙应用商店中没有出现过,所以我们负责立项的小伙伴打算叫这个名字。后面华为那边因为这个名字太有特点,需要我们提供这个名字的商标,才能允许上架。但是当初我们备案也是拿故事大王去备案、AGC 上的资料也全部都是故事大王,所以等于需要重新走一遍备案的流程,这个上架失败的事情,其实主要原因在于我,因为我昨晚把控流程的负责人,当初其实是感觉到这个名字有问题,但是后面因为某些原因没有细究。

这个也充分说明懂技术和做产品其实是两码事。需要把握的事项更多,其中,还需要注意的是,萤火故事屋里面引用的一些故事是否会侵权。假如,我在这里面引用了 大头儿子和小头爸爸的一些故事,会不会侵权呢 🙂,这个问题留给聪明的评论区的网友

总而言之吧,最后我们重新调整资料,萤火故事屋就顺利上线了。


核心开发人员
萤火故事屋的核心开发人员也很年轻呀,都是 25 届毕业的小伙伴。其中 1 个已经有几个鸿蒙项目的开发经验来,也是在工作之余抽空来主导项目的开发,另外一个 25 届的小伙伴要稍弱些,但是大部分的基础代码也是他完成了。

开发的小故事
开始组团打怪了

教小伙伴用用 git

执行力也很强

初步有成果

教一下开发规范

重命名时候的讨论

成就感最足的时候吧

🏗️ 架构设计
模块化架构
- entry 模块: 主入口模块,包含核心功能
- home 模块: 首页相关功能
- my 模块: 个人中心模块
- collect 模块: 收藏功能模块
- AppScope: 全局应用范围配置
目录结构设计
bash
entry/src/main/ets/
├── component/ # 通用组件
├── views/ # 视图组件
├── pages/ # 页面
├── utils/ # 工具类
├── Data/ # 数据管理
├── constants/ # 常量定义
└── storywidget/ # 小组件
🚀 核心技术亮点
1. 现代化 UI 组件体系
AtomicServiceNavigation 导航系统
typescript
// Index.ets
import {
AtomicServiceNavigation,
AtomicServiceTabs,
TabBarOptions,
TabBarPosition,
} from "@kit.ArkUI";
- 使用
AtomicServiceNavigation
实现现代化导航 - 支持路由栈管理
NavPathStack
- 集成
AtomicServiceTabs
底部标签导航
自定义 Builder 模式
typescript
@Builder
navigationContent() {
Column() {
AtomicServiceTabs({
tabContents: [
() => {
this.tabContent1()
},
() => {
this.tabContent4()
}
],
tabBarOptionsArray: [
new TabBarOptions($r('app.media.icon_shouye'), '首页', $r('app.color.bottom_icon'), '#ff39a7b5'),
new TabBarOptions($r('app.media.icon_wode'), '我的', $r('app.color.bottom_icon'), '#ff39a7b5'),
],
2. 深色模式完整解决方案
系统级深色模式支持
typescript
import { ConfigurationConstant } from "@kit.AbilityKit"
@CustomDialog
export struct blackMode {
controller: CustomDialogController
@StorageLink('isOn') isOn:boolean = true
@StorageLink('isNormal') isNormal:boolean = true
setModel() {
const appContext = getContext().getApplicationContext()
if (this.isOn) {
appContext.setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET)
} else {
appContext.setColorMode(this.isNormal ? ConfigurationConstant.ColorMode.COLOR_MODE_LIGHT :
ConfigurationConstant.ColorMode.COLOR_MODE_DARK)
}
}
技术特点:
- 支持跟随系统模式
- 手动切换亮色/暗色模式
- 使用
@StorageLink
实现全局状态管理 - 自定义对话框组件实现设置界面
3. 沉浸式全屏体验
智能全屏管理
typescript
import { window } from "@kit.ArkUI";
import {
AREA_BOTTOM,
AREA_TOP,
ENTRY_ABILITY_CONTEXT,
} from "../constants/Index";
class FullScreen {
async enable() {
const ctx = AppStorage.get<Context>(ENTRY_ABILITY_CONTEXT);
let windowClass = await window.getLastWindow(ctx!);
windowClass.setWindowLayoutFullScreen(true);
//保证安全区域
const area = windowClass.getWindowAvoidArea(
window.AvoidAreaType.TYPE_SYSTEM
);
AppStorage.setOrCreate(AREA_TOP, px2vp(area.topRect.height));
const area2 = windowClass.getWindowAvoidArea(
window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR
);
AppStorage.setOrCreate(AREA_BOTTOM, px2vp(area2.bottomRect.height));
}
}
技术亮点:
- 自动计算安全区域避让
- 状态栏和导航栏高度适配
- 单例模式封装全屏管理
4. 网络请求架构
基于 Axios 的 HTTP 封装
typescript
import axios, {
AxiosError,
AxiosRequestConfig,
AxiosResponse,
InternalAxiosRequestConfig,
} from "@ohos/axios";
export const instance = axios.create({
baseURL: "",
});
// 添加请求拦截器
instance.interceptors.request.use(
(config: InternalAxiosRequestConfig) => {
"Content-Type: application/x-www-form-urlencoded";
return config;
},
(error: AxiosError) => {
return Promise.reject(error);
}
);
// 响应拦截器
instance.interceptors.response.use(
(response: AxiosResponse) => {
return response.data;
},
(error: AxiosError) => {
return Promise.reject(error);
}
);
class Http {
request<T, R = null>(config: AxiosRequestConfig) {
type IAxiosResponse = AxiosResponse<T>;
return instance<T, IAxiosResponse, R>(config).then((res) => {
return Promise.resolve(res as T);
});
}
}
特色功能:
- TypeScript 泛型支持
- 请求/响应拦截器
- 统一错误处理
- 链式调用 API
5. 广告集成系统
原生广告组件
typescript
import { advertising } from "@kit.AdsKit";
export class NativeAdUtil {
private ads: Array<advertising.Advertisement> = [];
private context: common.UIAbilityContext = getContext(
this
) as common.UIAbilityContext;
requestAd() {
const adDisplayOptions: advertising.AdDisplayOptions = {
mute: false,
};
const nativeVideoAdReqParams: advertising.AdRequestParams = {
adId: "g22kxp6lfs",
adType: 3,
adCount: 1,
enableDirectReturnVideoAd: true,
};
const adLoaderListener: advertising.AdLoadListener = {
onAdLoadFailure: (errorCode: number, errorMsg: string) => {
hilog.error(
0x0000,
"testTag",
"%{public}s",
`Failed to request ad, message: ${errorMsg}, error code: ${errorCode}`
);
},
onAdLoadSuccess: (ads: Array<advertising.Advertisement>) => {
emitter.emit("NativeAdPage", {
data: { ads: ads, adDisplayOptions: adDisplayOptions },
});
},
};
}
}
广告特性:
- 支持原生广告和插屏广告
- 事件驱动的广告加载
- 完整的错误处理机制
- 广告内容分级控制
6. 状态管理体系
多层级状态管理
typescript
@StorageProp(AREA_TOP)
safeTop: number = 0
@StorageProp(AREA_BOTTOM)
safeBottom: number = 0
@StorageProp('isOn') isOn: boolean = true
@StorageProp('isNormal') isNormal: boolean = true
@Provide("pageStack")
pageStack: NavPathStack = new NavPathStack()
状态管理策略:
@StorageProp
: 全局持久化状态@Provide/@Consume
: 跨组件状态传递@State
: 组件内部状态@Watch
: 状态变化监听
7. 智能搜索系统
动态搜索提示
typescript
titleArr() {
const resProverbsAll = this.proverbsAll.map((item: ProverbsDetail) => {
return item.text
})
const resRiddlesArr = this.riddlesArr.map((item: RiddlesObj) => {
return item.question
})
const resStoryDetailsAll = this.storyDetailsAll.map((item: StoryDetailsObj) => {
return item.title
})
const resTopTabsRiddleArr = this.topTabsRiddleArr.map((item: TopTabsRiddle) => {
return item.title
})
this.TitleArr.push(...resProverbsAll, ...resRiddlesArr, ...resStoryDetailsAll, ...resTopTabsRiddleArr)
}
Title() {
const res = Math.floor(Math.random() * this.TitleArr.length);
this.title = this.TitleArr[res]
}
搜索特色:
- 多数据源聚合搜索
- 随机搜索提示轮播
- 定时器控制搜索框动效
8. 性能优化技巧
视图可见性优化
typescript
.onVisibleAreaChange([0, 1], (isVisible) => {
if (isVisible) {
const res = setInterval(() => {
this.Title()
console.log('你是猪')
}, 3000)
this.setIntervalID = res
} else {
clearInterval(this.setIntervalID)
}
})
优化策略:
- 基于可见性的定时器管理
- 避免不必要的后台计算
- 内存泄漏预防
9. 趣味交互设计
随机励志语录弹窗
typescript
@State messageList: string[] = [
'成长不是一蹴而就,每一次错误都是成长的台阶,勇于犯错,才能更快抵达成熟的彼岸。',
'学习如同登山,每一步攀登都可能艰辛,但每一次登高都会让你看到更美的风景。',
// ... 更多励志语录
]
.onClick(() => {
this.handlePopup = true
if(this.handlePopup){
this.Message = this.messageList[Math.floor(Math.random() * this.messageList.length)]
}
})
交互亮点:
- 随机励志语录系统
- 浮动卡片设计
- 阴影和圆角现代化 UI
🛠️ 编程技巧总结
1. ArkTS 最佳实践
- 严格的类型定义
- 泛型编程应用
- 接口定义规范
2. 组件化设计模式
- 高内聚低耦合组件
- 可复用 UI 组件库
- 统一的组件接口
3. 异步编程处理
- Promise 链式调用
- async/await 语法
- 错误边界处理
4. 内存管理优化
- 定时器生命周期管理
- 事件监听器清理
- 组件销毁时的资源释放
5. 用户体验优化
- 加载状态管理
- 错误状态友好提示
- 流畅的页面转场动效
📱 设备适配特性
- 多设备支持: 手机和平板适配
- 安全区域适配: 全面屏设备支持
- 响应式布局: 不同屏幕尺寸自适应
- 深色模式: 系统级主题切换
总结
如果你兴趣想要了解更多的鸿蒙应用开发细节和最新资讯 ,甚至你想要做出一款属于自己的应用!欢迎在评论区留言或者私信或者看我个人信息,可以加入技术交流群。
