《宠知汇》应用案例热点技术解析
开篇
《宠知汇》作为一款深度适配 HarmonyOS 的宠物主题应用,汇聚专业养宠知识,构建全场景养护生态,为
宠物主人打造覆盖宠物生命周期的一站式智慧服务入口。
依托鸿蒙系统的分布式能力与智能化特性,让科学养宠更简单、更便捷。
《宠知汇》借助 HarmonyOS 的跨设备优势,实现手机、平板、智慧屏等多终端的无缝协同,成为宠物主人身边的 移动养宠管家。
第一章:借助“一多”能力,实现全设备适配
《宠知汇》通过 HarmonyOS 的一次开发,多端部署能力,实现了应用在不同设备形态上的完美适配。基于统一的 ArkTS 开发框架,应用能够智能识别设备类型和屏幕尺寸,自动调整界面布局和交互方式。
需要掌握一次开发、多端部署的知识,就需要了解一多和三层架构的关系。
三层架构
想象你要开发一个应用,就像建一栋能适配不同住户(设备)的智能公寓楼。三层架构就是把这栋楼分成三个部分,每层各司其职:
公共能力层(地下室和基础设施)
这是整栋楼的“地基”,包含水管、电网、网络线路等共享资源。
在应用中,就是公共组件:比如统一的按钮样式、网络请求工具、数据管理库等。所有上层功能都能调用这些基础能力,避免重复造轮子。
通俗说:就像楼里的公用健身房和停车场,所有住户都能用,但不需要每家自己修。
基础特性层(标准户型模块)
这层是预先设计好的功能模块,比如卧室、厨房、卫生间。每个模块独立且完整(高内聚),能灵活组合。
在应用中,就是核心功能:比如登录模块、支付模块、视频播放模块等。这些模块可以打包成 功能包(Feature HAP),根据需要安装到不同设备。
通俗说:就像乐高积木,你可以用同样的积木块拼出不同房子,比如手机版用少量积木,平板版用更多积木。
产品定制层(个性化装修和入口)
这层是针对不同住户(设备)的个性化定制。比如给年轻人的公寓用现代风格,给家庭的用温馨风格。
在应用中,就是设备专属的 UI 和配置:比如手机的简洁界面、平板的分屏布局、PC 的窗口模式。这一层编译成 入口包(Entry HAP),作为用户直接交互的界面。
通俗说:同样是卧室模块,在手机上显示为底部标签,在平板上显示为侧边栏,但背后的功能(睡觉)是一样的。
为什么这样分层?
维护简单:如果水管坏了(公共能力层更新),只需修一次,全楼受益。
灵活扩展:想新增一个“智能厨房”(新功能),只需在基础特性层开发,然后轻松添加到不同户型(设备)。
复用性强:同样的厨房模块,既能用在公寓,也能用在别墅(不同设备)。
实际开发中,可以参考以下表格来了解三层架构。
表格已提炼每一层的核心维度,覆盖开发中最需关注的 产物、作用和规则,便于快速查阅和对比。
对应 《宠知汇》目录结构
一次开发、多端部署
根据一次开发、多端部署的理念,一多又可以分为三种一多,它们分别是 界面级一多、工程级一多和能力级一多。
工程级一多是基础和骨架。它决定了代码怎么组织、怎么打包。
功能级一多是神经和肌肉。它让应用能感知并适应设备的硬件能力,确保功能上的兼容性。
界面级一多是外表和皮肤。它最终决定了用户在屏幕上看到的是什么样子,确保视觉和交互的完美体验。
其中工程级一多,就是上面刚刚描述过的三层架构。
功能级一多
手机上支持拍照,手表上不支持,那么一套代码下,该如何完美解决?
答案是借助 即 SystemCapability,缩写为 SysCap。
和硬件相关的如摄像、麦克风、wifi 等都是系统的能力。每一个系统能力对应多个 API,支持某个系统能力也等于支持这些 API 调用。
系统能力又分为支持能力集、联想能力集和要求能力集三个核心概念。
支持能力集:设备具备的系统能力集合,在设备配置文件中配置。
要求能力集:应用需要的系统能力集合,在应用配置文件中配置。
联想能力集:开发应用时 DevEco Studio 可联想的 API 所在的系统能力集合,在应用配置文件中配置。
开发多设备应用时,工程中默认的要求能力集是多个设备支持能力集的交集,默认的联想能力集是多个设备支持能力集的并集。
如果某个系统能力没有写入应用的要求能力集中,那么在使用前需要判断设备是否支持该系统能力。
方法 1:canIUse()接口帮助开发者来判断该设备是否支持某个特定的 syscap。
if (canIUse('SystemCapability.Communication.NFC.Core')) { hilog.info(0x0000, 'Index', `该设备支持SystemCapability.Communication.NFC.Core`); } else { hilog.error(0x0000, 'Index', `该设备不支持SystemCapability.Communication.NFC.Core`); }
Index.ets
方法 2:开发者可通过 import 的方式将模块导入,若当前设备不支持该模块,import 的结果为 undefined,开发者在使用其 API 时,需要判断其是否存在。
import { nfcController } from '@kit.ConnectivityKit';@Entry @Component struct Index { // ... canIUseNfc(): void { if (canIUse('SystemCapability.Communication.NFC.Core')) { hilog.info(0x0000, 'Index', `该设备支持SystemCapability.Communication.NFC.Core`); } else { hilog.error(0x0000, 'Index', `该设备不支持SystemCapability.Communication.NFC.Core`); } // ... } // ... }
配置联想能力集和要求能力集
DevEco Studio 会根据创建的工程所支持的设备自动配置联想能力集和要求能力集,同时也支持开发者修改。
// syscap.json{ "devices": { "general": [ "default", "tablet" ], "custom": [ { "Custom Device": [ "SystemCapability.Communication.SoftBus.Core" ] } ] }, "development": { "addedSysCaps": [ "SystemCapability.Communication.NFC.Core" ] }, "production": { "addedSysCaps": [], "removedSysCaps": [] }}
复制代码
另外,实际开发中,如果想要实现某一段功能代码,可以根据用户系统的 API 版本进行调整,
可以使用 @kit.BasicServicesKit 中的 sdkApiVersion 来实现,如
if(deviceInfo.sdkApiVersion===20){ console.log("API20") }
复制代码
或者在 ArkUI 中使用
if (this.sdkApiVersion >= 20) {Text('应用20')} else {Text('应用不是20')}
复制代码
界面级一多
界面一多指的是如何使用一套代码,实现适配多种宽度不同的设备,HarmonyOS 中提供的解决方案主要有
自适应布局
响应式布局
所谓的自适应布局可以理解为就是页面布局元素可以跟随屏幕的大小变化而等比例变化。
响应式布局则是可以根据不同的条件,实现屏幕布局更大的变化,如
大屏幕,一行显示 4 个卡片
小屏幕,一行显示 1 个卡片。
自适应布局比较好实现,像 flex 容器、grid、线性布局等可以跟随屏幕宽度变化而变化的容器,都可以轻易实现自适应布局,结合尺寸的百分百单位,或者 layoutWeight 属性,页面元素也可以直接实现自适应布局。
针对常见的开发场景,方舟开发框架提炼了七种自适应布局能力,这些布局可以独立使用,也可多种布局叠加使用。
更加常用的其实是响应式布局
响应式布局有四种实现方式,其中它们又可以互相搭配和关联,它们分别是断点、媒体查询以及栅格布局以及响应式工具。
**断点 (Breakpoints)**将设备的窗口宽度(或高宽比)划分为几个关键的范围(区间)
xs (超小): 0 ~ 320vp (智能穿戴)
sm (小): 320vp ~ 600vp (手机竖屏)
md (中): 600vp ~ 840vp (平板竖屏/折叠屏)
lg (大): 840vp ~ 1440vp (平板横屏/PC)
xl (超大): 1440vp 及以上 (大屏设备)
image-20251030221518090
实际开发中,可以监听屏幕尺寸的变化,然后把断点存储在全局中,方便使用。宠知汇 就是采用这种方式。
宠知汇的屏幕适配流程
1. V2 状态管理设计
文件:commons/base/src/main/ets/utils/BreakpointSystem.ets
全局状态类定义:
// 全局断点状态管理(V2)@ObservedV2class BreakpointState { @Trace currentBreakpoint: string = 'sm';}// 创建全局单例const breakpointState = new BreakpointState();// 导出供其他模块使用export { breakpointState };
复制代码
关键设计要点:
断点配置:
interface Breakpoint { name: string; size: number;}private breakpoints: Breakpoint[] = [ { name: 'xs', size: 0 }, // 超小屏(0-320vp) { name: 'sm', size: 320 }, // 小屏(320-600vp) { name: 'md', size: 600 }, // 中屏/平板(600-840vp) { name: 'lg', size: 840 } // 大屏/折叠屏(840vp+)];
复制代码
断点划分遵循 HarmonyOS 官方建议,覆盖主流设备尺寸:
xs/sm:手机竖屏模式
md:平板或手机横屏
lg:大屏平板、折叠屏展开状态
2. 窗口尺寸监听机制
在 API 18 中,推荐使用 window.on('windowSizeChange') 替代已废弃的 mediaquery.matchMediaSync:
// 注册断点监听public register(windowClass: window.Window): void { try { this.windowClass = windowClass; this.uiContext = windowClass.getUIContext(); // 获取初始窗口尺寸并计算断点 const windowProperties = windowClass.getWindowProperties(); const initialWidth = this.uiContext.px2vp(windowProperties.windowRect.width); const initialBreakpoint = this.calculateBreakpoint(initialWidth); this.updateCurrentBreakpoint(initialBreakpoint); // 监听窗口尺寸变化 this.windowSizeChangeCallback = (size: window.Size) => { if (this.uiContext) { const newWidth = this.uiContext.px2vp(size.width); const newBreakpoint = this.calculateBreakpoint(newWidth); this.updateCurrentBreakpoint(newBreakpoint); } }; windowClass.on('windowSizeChange', this.windowSizeChangeCallback); console.info('[BreakpointSystem] Window size change listener registered'); } catch (err) { console.error(`[BreakpointSystem] Failed to register: ${JSON.stringify(err)}`); }}
复制代码
关键技术点:
使用 window.getWindowProperties() 获取窗口实际尺寸
通过 UIContext.px2vp() 进行像素到虚拟像素的转换
监听窗口尺寸变化事件,支持分屏、折叠屏等场景
3. V2 状态更新机制
状态初始化:
// 注册断点监听时初始化状态const windowProperties = windowClass.getWindowProperties();const initialWidth = this.uiContext.px2vp(windowProperties.windowRect.width);const initialBreakpoint = this.calculateBreakpoint(initialWidth);// 直接更新 V2 状态this.state.currentBreakpoint = initialBreakpoint;// 同步到 AppStorage(兼容旧版订阅)AppStorage.setOrCreate<string>('currentBreakpoint', initialBreakpoint);
复制代码
窗口尺寸变化响应:
this.windowSizeChangeCallback = (size: window.Size) => { if (this.uiContext) { const newWidth = this.uiContext.px2vp(size.width); const newBreakpoint = this.calculateBreakpoint(newWidth); // 仅在断点实际变化时更新 if (this.state.currentBreakpoint !== newBreakpoint) { // V2 状态自动触发响应式更新 this.state.currentBreakpoint = newBreakpoint; // 同步到 AppStorage AppStorage.setOrCreate<string>('currentBreakpoint', newBreakpoint); console.info(`[BreakpointSystem] Breakpoint changed to: ${newBreakpoint}`); } }};
复制代码
V2 状态管理优势:
精准追踪:@Trace 装饰器实现属性级别的变化追踪
自动更新:状态变化自动触发订阅组件的 UI 刷新
性能优化:仅在断点实际变化时触发更新,避免不必要的重渲染
双向兼容:V2 状态与 AppStorage 双向同步,支持新旧两种订阅方式
4. 应用生命周期集成
文件:products/phone/src/main/ets/entryability/EntryAbility.ets
export default class EntryAbility extends UIAbility { private breakpointSystem: BreakpointSystem = new BreakpointSystem(); onWindowStageCreate(windowStage: window.WindowStage): void { windowStage.loadContent('pages/Index', (err) => { if (err.code) { hilog.error(DOMAIN, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err)); return; } // 注册断点监听,传入 Window 实例 this.breakpointSystem.register(windowStage.getMainWindowSync()); }); } onWindowStageDestroy(): void { // 注销断点监听 this.breakpointSystem.unregister(); hilog.info(DOMAIN, 'testTag', 'Breakpoint system unregistered'); }}
复制代码
生命周期管理:
5. 断点值映射工具
// 断点类型映射export interface BreakpointTypeOption<T> { xs?: T; sm?: T; md?: T; lg?: T;}// 断点值映射工具类export class BreakpointType<T> { private options: BreakpointTypeOption<T>; constructor(options: BreakpointTypeOption<T>) { this.options = options; } getValue(breakpoint: string): T | undefined { if (breakpoint === 'xs') return this.options.xs; if (breakpoint === 'sm') return this.options.sm; if (breakpoint === 'md') return this.options.md; if (breakpoint === 'lg') return this.options.lg; return undefined; }}
复制代码
BreakpointType 提供了类型安全的断点值映射机制,支持任意类型的响应式配置。
6. UI V2 组件状态管理
文件:products/phone/src/main/ets/pages/HomePage.ets
组件状态定义:
// 页面状态类(V2)@ObservedV2class HomePageState { @Trace currentPetIndex: number = 0; @Trace showPetTip: boolean = false; @Trace petTipText: string = '';}// 组件定义@Componentexport struct HomePage { state: HomePageState = new HomePageState(); @StorageProp('currentBreakpoint') currentBreakpoint: string = 'sm'; build() { Column() { Scroll() { Column({ space: new BreakpointType({ xs: 16, sm: 20, md: 24, lg: 28 }).getValue(this.currentBreakpoint) || 20 }) { // 页面内容 } .padding({ left: new BreakpointType({ xs: 16, sm: 16, md: 24, lg: 32 }).getValue(this.currentBreakpoint) || 16, right: new BreakpointType({ xs: 16, sm: 16, md: 24, lg: 32 }).getValue(this.currentBreakpoint) || 16 }) } } }}
复制代码
通过 @StorageProp 订阅全局断点状态,根据不同断点动态调整:
页面间距与尺寸适配:
build() { Column() { Scroll() { Column({ space: new BreakpointType({ xs: 16, sm: 20, md: 24, lg: 28 }).getValue(this.currentBreakpoint) || 20 }) { // 页面内容 } .padding({ left: new BreakpointType({ xs: 16, sm: 16, md: 24, lg: 32 }).getValue(this.currentBreakpoint) || 16, right: new BreakpointType({ xs: 16, sm: 16, md: 24, lg: 32 }).getValue(this.currentBreakpoint) || 16 }) } }}
复制代码
通过 @StorageProp 订阅全局断点状态,根据不同断点动态调整:
7. 栅格布局响应式配置
Grid() { GridItem() { this.buildFeatureCard('领养', '🐾', ...) } GridItem() { this.buildFeatureCard('寄养', '🏡', ...) } GridItem() { this.buildFeatureCard('医疗', '🏥', ...) } GridItem() { this.buildFeatureCard('美容', '✨', ...) }}.columnsTemplate( new BreakpointType({ xs: '1fr 1fr', // 手机:2列 sm: '1fr 1fr', // 小屏:2列 md: '1fr 1fr 1fr 1fr', // 平板:4列 lg: '1fr 1fr 1fr 1fr' // 大屏:4列 }).getValue(this.currentBreakpoint) || '1fr 1fr').rowsTemplate( new BreakpointType({ xs: '1fr 1fr', // 手机:2行 sm: '1fr 1fr', md: '1fr', // 平板:1行 lg: '1fr' }).getValue(this.currentBreakpoint) || '1fr 1fr').columnsGap( new BreakpointType({ xs: 12, sm: 12, md: 16, lg: 20 }).getValue(this.currentBreakpoint) || 12)
复制代码
响应式布局策略:
手机端(xs/sm):2 列 2 行,紧凑布局
平板端(md/lg):4 列 1 行,横向展开
8. 字体与图标尺寸适配
Text('爱宠之家') .fontSize(new BreakpointType({ xs: 20, sm: 20, md: 24, lg: 28 }).getValue(this.currentBreakpoint) || 20) .fontWeight(FontWeight.Bold)Image($r('app.media.pet_heart')) .width(new BreakpointType({ xs: 32, sm: 32, md: 40, lg: 48 }).getValue(this.currentBreakpoint) || 32) .height(new BreakpointType({ xs: 32, sm: 32, md: 40, lg: 48 }).getValue(this.currentBreakpoint) || 32)
复制代码
9. 条件布局切换
// 故事卡片 - 在平板上使用横向布局if (this.currentBreakpoint === 'md' || this.currentBreakpoint === 'lg') { Row({ space: new BreakpointType({ md: 16, lg: 20 }).getValue(this.currentBreakpoint) || 16 }) { this.buildStoryCard('小橘的新家', '...', '2小时前') this.buildStoryCard('旺财的康复日记', '...', '1天前') }} else { Column({ space: 12 }) { this.buildStoryCard('小橘的新家', '...', '2小时前') this.buildStoryCard('旺财的康复日记', '...', '1天前') }}
复制代码
根据断点切换布局方向,提升大屏设备的空间利用率。
10. 内容宽度约束
.width('100%').constraintSize({ maxWidth: this.currentBreakpoint === 'xs' || this.currentBreakpoint === 'sm' ? '100%' : this.currentBreakpoint === 'md' ? 800 : 1200})
复制代码
在大屏设备上限制内容最大宽度,避免内容过度拉伸导致阅读体验下降。
11. 全局状态订阅模式
直接订阅 V2 状态
import { breakpointState } from 'base';@ComponentV2export struct SomePage { // 直接引用全局状态 private breakpoint = breakpointState; build() { Text(this.breakpoint.currentBreakpoint) }}
复制代码
第二章:HarmonyOS 智能体,实现智能化宠物服务
《宠知汇》背后依靠海量的宠物饲养百科技术,包含有宠物种类、喂养食物、陪伴技巧、注意事项等等专业知识,利用 HarmonyOS 上的智能体知识打造出配套可用的智能体,给广大 HarmonyOS 用户提供贴心帮助。
利用 Agent Framework Kit 功能实现在应用内拉起相关智能体,第一时间提供给用户使用的宠物饲养知识。
开发者接入智能体只需要两个步骤
小艺智能体平台中创建智能体
你的应用中引入智能体
创建智能体
1. 登录小艺智能体平台
https://developer.huawei.com/consumer/cn/hag/abilityportal/#/
登录华为账号即可
2. 快速创建智能体
在小艺智能体平台,智能体是一个最终的产品,智能体可以通过知识库、工作流、和资源来增强自身的功能。
3. 配置智能体
刚入门的小伙伴可以选择 单 Agent (LLM 模式)
智能体提供了很多配置项
这些配置从交互开场、多模态体验、功能扩展、自动化流程、数据管理及用户引导等方面,全方位定制智能体的交互方式、功能范围与运行逻辑,助力其实现个性化、高效且专业的服务。
4. 发布上架智能体
如果都编辑完毕了,可以申请上架了
如果上架成功,想要让这个智能体给你的鸿蒙应用服务,需要在配置页面中,添加你的应用
最后需要记住这个智能体的 agentId,编码中需要用到的。
代码中集成
1. 导入依赖
import { BusinessError } from '@kit.BasicServicesKit';import { hilog } from '@kit.PerformanceAnalysisKit';import { FunctionComponent, FunctionController } from '@kit.AgentFrameworkKit';
复制代码
2. 声明控制器与智能体标识
// 智能体控制器(用于监听对话框打开/关闭等事件)private agentController: FunctionController = new FunctionController();// 智能体实例标识(需替换为实际可用的 agentId)private agentId: string = 'agenta6912c10c332438aa25f7e25da306eba';
复制代码
3. 生命周期中注册/释放事件监听
aboutToAppear() { // 初始化事件监听器 this.initAgentListeners();}aboutToDisappear() { // 释放事件监听器,避免内存泄漏 this.agentController?.off('agentDialogOpened'); this.agentController?.off('agentDialogClosed');}// 统一初始化监听initAgentListeners() { this.agentController?.on('agentDialogOpened', this.onAgentOpenedCallback); this.agentController?.on('agentDialogClosed', this.onAgentClosedCallback);}// 回调方法onAgentOpenedCallback = () => { hilog.info(0x0001, 'HomePage', '智能体弹窗已打开');}onAgentClosedCallback = () => { hilog.info(0x0001, 'HomePage', '智能体弹窗已关闭');}
复制代码
4. 在页面中渲染 FunctionComponent
@BuilderbuildAIAssistantButton() { // 放置位置可根据页面布局自行调整 Column() { FunctionComponent({ agentId: this.agentId, onError: (err: BusinessError) => { hilog.error(0x0001, 'HomePage', `智能体错误: ${JSON.stringify(err)}, message: ${err.message}`); }, options: { title: '你的宠物百科', isShowShadow: true }, controller: this.agentController }) } .margin({ right: 16, // 可结合断点系统做响应式 bottom: 80 })}
复制代码
说明:
agentId 用于绑定具体的智能体能力。
controller 负责事件监听与交互控制。
onError 对接错误处理与日志记录。
options 可配置标题与视觉效果等。
5. 完整最小示例(页面片段)
@Componentexport struct HomePage { private agentController: FunctionController = new FunctionController(); private agentId: string = 'agenta6912c10cxxxxxxxxxxxxxx'; aboutToAppear() { this.initAgentListeners(); } aboutToDisappear() { this.agentController?.off('agentDialogOpened'); this.agentController?.off('agentDialogClosed'); } initAgentListeners() { this.agentController?.on('agentDialogOpened', () => { hilog.info(0x0001, 'HomePage', '智能体弹窗已打开'); }); this.agentController?.on('agentDialogClosed', () => { hilog.info(0x0001, 'HomePage', '智能体弹窗已关闭'); }); } build() { // ...页面主体内容 // 在右下角叠加智能体入口 Stack({ alignContent: Alignment.BottomEnd }) { // ...其他内容 this.buildAIAssistantButton() } .width('100%') .height('100%') } @Builder buildAIAssistantButton() { Column() { FunctionComponent({ agentId: this.agentId, onError: (err: BusinessError) => { hilog.error(0x0001, 'HomePage', `智能体错误: ${JSON.stringify(err)}, message: ${err.message}`); }, options: { title: '你的宠物百科', isShowShadow: true }, controller: this.agentController }) } .margin({ right: 16, bottom: 80 }) }}
复制代码
6. 常见问题与建议
智能体 API 能力提示:部分设备或 API 版本可能提示"系统能力不支持",请确保目标设备及系统版本支持 AgentFramework 能力。
agentId 必须为有效的智能体标识;如无效会触发 onError。
事件监听务必在 aboutToDisappear 释放,避免资源泄漏。
放置位置与样式可结合现有断点系统进行响应式适配。
第三章:其他优秀 Harmony6 特性
1. enableDataDetector - 智能实体识别
全新的智能实体识别能力,能够自动识别文本中的电话号码、邮箱、网址、地址等实体信息。
实际应用:
Text('邮箱:yeah126139163@163.com') .enableDataDetector(true) // 启用实体识别 .dataDetectorConfig({ // 支持识别类型:PHONE_NUMBER、URL、EMAIL、ADDRESS、DATE_TIME types: [], // 空数组表示识别所有类型 onDetectResultUpdate: (result: string) => { // 识别结果回调处理 } })
复制代码
2. showCommentDialog - 应用商店评论对话框
拿已经上架 作品演示
鸿蒙 6 新增的应用商店评论 API,可在应用内直接调起评论对话框。
const uiContext = this.getUIContext().getHostContext() as common.UIAbilityContext;commentManager.showCommentDialog(uiContext).then(() => { hilog.info(0, 'TAG', "评论对话框显示成功");}).catch((error: BusinessError<Object>) => { // 处理用户短期内已评论的情况 this.getUIContext().getPromptAction().showToast({ message: `您短期内已经评论过了` });});
复制代码
3. shaderStyle - 着色器样式渲染
鸿蒙 6 引入的 GPU 加速着色器渲染技术,支持渐变色、阴影等高级视觉效果。
Text('应用名称') .shaderStyle({ colors: [[Color.Red, 0], [Color.Orange, 1]], // 渐变色配置 direction: GradientDirection.Right // 渐变方向 })
复制代码
4. animationCurve - 动画曲线优化
鸿蒙 6 优化的动画曲线系统,提供更自然流畅的动画效果。
Tabs({ index: $$this.currentTabIndex }) .onChange((index: number) => { this.currentTabIndex = index; }) .animationCurve(Curve.EaseInOut) // 缓入缓出动画曲线
复制代码
5. 文本翻牌动效 contentTransition
@Entry@ComponentV2struct ScheduleDetailPage { @Local number: number = 5; @Local numberTransition: NumericTextTransition = new NumericTextTransition({ flipDirection: FlipDirection.DOWN, enableBlur: false }); build() { Column() { Text(this.number + "") .borderWidth(1) .fontSize(40) .contentTransition(this.numberTransition) Button("chang number") .onClick(() => { this.number++; }) .margin(10) } .height('100%') .width('100%') }}
复制代码
结言
以极小的代码代价让《宠知汇》接入了鸿蒙新的特性,通过引入了一多、智能体能力,HarmonyOS 应用上实现了其他系统没有的创新体验,带给用户丝滑、流畅的体验。
评论