.mode(NavigationMode.Auto)
2.模块全屏的使用以及Bug解决
在EntryView的Navigation中设置navBarWidth,其值设置为由@Provide装饰器装饰过的变量,默认值为50%,作用是为了适配必要全屏的模块。 现在只有折叠屏音乐播放器案例必要全屏,在对应模块的实现文件声明由@Consume装饰器装饰过的变量,更改变量的值就可以实现与子女组件双向同步的通讯,从而改变 EntryView中navBarWidth的宽度。
这只实现了全屏变换,但是原来Navigation更换模块时会有一个动画,会与全屏变换动画冲突,右半屏会出现上一个模块画面一闪而过的bug。这必要更改isNeedFullScreen的值来控制 路由跳转时是否有动画显示。
源码参考:
DynamicsRouter.ets
MusicPlayerInfoComp.ets
EntryView.ets
// EntryView.ets
…
@Provide(‘isFullScreen’) isFullScreen: string = ‘50%’;
…
Navigation(this.pageStack) { … }
.backgroundColor($r(‘app.color.main_background_color’))
.hideTitleBar(true)
.navBarWidth(this.isFullScreen)
.navDestination(this.pageMap)
.mode(NavigationMode.Auto)
…
// MusicPlayerInfoComp.ets
…
@Consume(‘isFullScreen’) isFullScreen: string;
…
aboutToAppear(): void {
…
// 潜伏navigation导航栏,设置为全屏。
animateTo({
duration: 400,
curve: Curve.EaseInOut,
}, () => {
this.isFullScreen = ‘0.01%’;
})
…
}
…
build() {
Flex({ direction: this.curFlexDirection }) {
Image( r ( ′ a p p . m e d i a . i c p u b l i c b a c k ′ ) ) . w i d t h ( r('app.media.ic_public_back')) .width( r(′app.media.icpublicback′)).width(r(‘app.integer.font_size_music_title’))
.height($r(‘app.integer.font_size_music_title’))
.onClick(() => {
DynamicsRouter.pop()
// 呈现navigation导航栏,设置为半屏。
animateTo({
duration: 200,
curve: Curve.EaseInOut,
}, () => {
this.isFullScreen = ‘50%’;
})
})
.position({ x: $r(‘app.integer.image_position_x’), y: $r(‘app.integer.image_position_y’) })
.fillColor(Color.White)
…
}
}
//DynamicsRouter.ets
public static async push(routerInfo: RouterInfo, param?: string): Promise {
…
// 模块是否必要转场动画
let isNeedFullScreen: boolean = true;
// TODO:知识点:通过动态import的方式引入模块,在必要进入页面时才加载模块,可以镌汰主页面的初始化时间及占用的内存
await import(moduleName).then((result: ESObject) => {
…
if (FullScreenArray.includes(moduleName)) {
isNeedFullScreen = false;
}
}, (error: ESObject) => {
// 动态加载模块失败时,打印错误日志
logger.error(LOGGER_TAG, error);
});
if (isImportSucceed) {
…
// 查找到对应的路由栈进行跳转
DynamicsRouter.getNavPathStack().pushPath({ name: builderName, param: param }, isNeedFullScreen);
…
}
}
3.主页Navigation弹出路由栈
手机的Navigation采用Stack模式,手势右滑退出会自动pop路由栈,但是采用分栏可以直接点击跳转到下一模块,那么就必要在点击瀑布流的FlowItem的时间pop上一个路由栈。
源码参考FunctionalScenes.ets。
@Builder
methodPoints(listData: SceneModuleInfo) {
…
.onClick(() => {
DynamicsRouter.pop();
// 点击瀑布流Item时,根据点击的模块信息,将页面放入路由栈
DynamicsRouter.push(listData.routerInfo, listData.param);
})
}
FAQ
1.页面间共享组件实例模块的适配问题
页面间共享组件实例模块中也写了Navigation组件,想要展示的效果是Stack模式,但是半屏的平板的宽度也大于600,被体系自动认为采用Split模式。
页面间共享组件实例模块中还绑定了半模态,并未设置preferType(半模态页面的样式)。装备宽度小于600vp时,默认显示底部弹窗样式。 装备宽度在600-840vp间时,默认显示居中弹窗样式。装备宽度大于840vp时,默认显示跟手弹窗样式,跟手弹窗显示在bindSheet绑定的节点下方。平板宽度大于840vp,跟手弹窗显示在节点下方导致弹窗不可见。 以是通过装备宽度来设置preferType的样式。
源码参考:
ComponentSharedInPages.ets
TakeTaxiDetailPage.ets
//ComponentSharedInPages.ets
build() {
Stack({alignContent: Alignment.Bottom}) {
…
// 应用主页用NavDestination承载,Navigation为空页面直接跳转到MainPage主页面
Navigation(this.pageStackForComponentSharedPages) {
}
…
.mode(NavigationMode.Stack)
}
…
}
//TakeTaxiDetailPage.ets
…
@State windowWidth: number = 0;
readonly componentsWindowWidth: number = 600;
…
/**
- 获取应用主窗口的宽高
*/
aboutToAppear() {
window.getLastWindow(getContext(this), (err: BusinessError, data: window.Window) => {
let rect: window.Rect = data.getWindowProperties().windowRect;
this.windowWidth = px2vp(rect.width);
})
}
…
build() {
NavDestination() {
…
// 绑定上半模态页面,用于显示内容
.bindSheet($$this.isShow, this.taxiContentBuilder(),
{
detents: TakeTaxiPageCommonConstants.SHEET_DETENTS,
preferType: this.windowWidth > this.componentsWindowWidth ? SheetType.CENTER : SheetType.POPUP,
…
}
)
}
…
}
2.底部抽屉滑动效果模块的适配问题
底部抽屉滑动效果模块中写了一个Image组件,其资源是一个很大的舆图图片,在分栏效果展示时Image图片资源会拦截Navigation导航栏的点击或者拖拽事件,可以采用Column的clip属性将超出Image的图片裁掉。
源码参考:Component.ets。
build() {
Column() {
// 背景舆图图片
Image( r ( ′ a p p . m e d i a . m a p ′ ) ) . i d ( " b g i m g " ) . h e i g h t ( r('app.media.map')) .id("bg_img") .height( r(′app.media.map′)).id("bgimg").height(r(‘app.integer.number_2000’))
.width($r(‘app.integer.number_2000’))
.translate({ x: this.offsetX, y: this.offsetY })// 以组件左上角为坐标原点进行移动
.draggable(false) // 单指操纵拖动背景舆图
}.width(‘100%’)
.height(‘100%’)
.clip(true) // 舆图图片超出页面地区时裁剪掉
…
}
3.适配挖孔屏模块的适配问题
适配挖孔屏模块Image组件采用ImageFit.Cover添补图片,导致图片显示不完备,采用ImageFit.Fill,虽然图片变扁了,但是能完备显示,不影响详细功能。
源码参考 iggingHoleScreen.ets。
Image($r(‘app.media.2048game’))
.objectFit(ImageFit.Fill)
.width(‘100%’)
.height(‘100%’)
4.左右拖动切换图片模块的适配问题
左右拖动切换图片模块主要功能要及时记录手势拖动的距离,以此来进行盘算,以是宽度和高度要写固定命值,不能使用百分比。但是折叠屏手机折叠后会出现超出屏幕的情况,可采用缩小组件宽度的方式适配。
源码参考:
DragToSwitchPicturesView.ets
Constants.ets
integer.json
// DragToSwitchPicturesView.ets
@State dragRefOffset: number = 0; // 用来记录每次图标拖动的距离
@State imageWidth: number = 160; // 用来记录每次图标拖动完成后左侧Image的width宽度
@State leftImageWidth: number = 160; // 用来记录每次图标拖动时左侧Image的及时width宽度
@State rightImageWidth: number = 160; // 用来记录每次图标拖动时右侧Image的及时width宽度
…
PanGesture({ fingers: CONFIGURATION.PANGESTURE_FINGERS, distance: CONFIGURATION.PANGESTURE_DISTANCE })
.onActionStart(() => {
this.dragRefOffset = CONFIGURATION.INIT_VALUE; // 每次拖动开始时将图标拖动的距离初始化。
})
// TODO: 性能知识点: 该函数是体系高频回调函数,避免在函数中进行冗余或耗时操纵,比方应该镌汰或避免在函数打印日志,会有较大的性能损耗。
.onActionUpdate((event: GestureEvent) => {
// 通过监听GestureEvent事件,及时监听图标拖动距离
this.dragRefOffset = event.offsetX;
this.leftImageWidth = this.imageWidth + this.dragRefOffset;
this.rightImageWidth = CONFIGURATION.IMAGE_FULL_SIZE - this.leftImageWidth;
if (this.leftImageWidth >= CONFIGURATION.LEFT_IMAGE_RIGHT_LIMIT_SIZE) { // 当leftImageWidth大于等于310vp时,设置左右Image为固定值,实现制止滑动效果。
this.leftImageWidth = CONFIGURATION.LEFT_IMAGE_RIGHT_LIMIT_SIZE;
this.rightImageWidth = CONFIGURATION.RIGHT_IMAGE_RIGHT_LIMIT_SIZE;
} else if (this.leftImageWidth <= CONFIGURATION.LEFT_IMAGE_LEFT_LIMIT_SIZE) { // 当leftImageWidth小于等于30vp时,设置左右Image为固定值,实现制止滑动效果。
this.leftImageWidth = CONFIGURATION.LEFT_IMAGE_LEFT_LIMIT_SIZE;
this.rightImageWidth = CONFIGURATION.RIGHT_IMAGE_LEFT_LIMIT_SIZE;
}
})
.onActionEnd((event: GestureEvent) => {
if (this.leftImageWidth <= CONFIGURATION.LEFT_IMAGE_LEFT_LIMIT_SIZE) {
this.leftImageWidth = CONFIGURATION.LEFT_IMAGE_LEFT_LIMIT_SIZE;
this.rightImageWidth = CONFIGURATION.RIGHT_IMAGE_LEFT_LIMIT_SIZE;
this.imageWidth = CONFIGURATION.LEFT_IMAGE_LEFT_LIMIT_SIZE;
} else if (this.leftImageWidth >= CONFIGURATION.LEFT_IMAGE_RIGHT_LIMIT_SIZE) {
this.leftImageWidth = CONFIGURATION.LEFT_IMAGE_RIGHT_LIMIT_SIZE;
this.rightImageWidth = CONFIGURATION.RIGHT_IMAGE_RIGHT_LIMIT_SIZE;
this.imageWidth = CONFIGURATION.LEFT_IMAGE_RIGHT_LIMIT_SIZE;
} else {
this.leftImageWidth = this.imageWidth + this.dragRefOffset; // 滑动竣事时leftImageWidth等于左边原有Width+拖动距离。
this.rightImageWidth = CONFIGURATION.IMAGE_FULL_SIZE - this.leftImageWidth; // 滑动竣事时rightImageWidth等于340-leftImageWidth。
this.imageWidth = this.leftImageWidth; // 滑动竣事时ImageWidth等于leftImageWidth。
}
})
5.图片压缩模块的适配问题
图片压缩模块中Text组件的字号在折叠手机屏折叠状态下过大,文本会超出屏幕,可接纳缩小字号适配。
源码参考:ImageCompression.ets
6.图片缩放模块的适配问题
图片缩放模块中Image组件的宽度和高度由窗口的宽度和高度决定。由于屏幕宽度大于600vp要分栏,会导致图片过大。以是要判断是否分栏,若分栏则windowWidth的宽度减半。
源码参考:ImageContentView.ets
…
@State windowWidth: number = 0;
@State windowHeight: number = 0;
…
/**
- 获取应用主窗口的宽高
*/
aboutToAppear() {
window.getLastWindow(getContext(this), (err: BusinessError, data: window.Window) => {
let rect: window.Rect = data.getWindowProperties().windowRect;
this.windowWidth = px2vp(rect.width);
this.windowHeight = px2vp(rect.height);
if (this.windowWidth > this.componentsWindowWidth) {
this.windowWidth = this.windowWidth / 2;
}
data.on(“windowSizeChange”, (size: window.Size) => {
this.windowWidth = px2vp(size.width);
this.windowHeight = px2vp(size.height);
if (this.windowWidth > this.componentsWindowWidth) {
this.windowWidth = this.windowWidth / 2;
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数HarmonyOS鸿蒙开发工程师,想要提升技能,往往是本身探索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。本身不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年HarmonyOS鸿蒙开发全套学习资料》,初志也很简朴,就是渴望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零底子资料,也有适合3年以上经验的小搭档深入学习提升的进阶课程,根本涵盖了95%以上HarmonyOS鸿蒙开发知识点,真正体系化!
由于文件比较大,这里只是将部门目录大纲截图出来,每个节点内里都包含大厂面经、学习笔记、源码讲义、实战项目、解说视频,而且会持续更新
如果你觉得这些内容对你有帮助,可以添加VX:vip204888 (备注鸿蒙获取)
一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感爱好的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、口试辅导),让我们一起学习成长!
伴深入学习提升的进阶课程,根本涵盖了95%以上HarmonyOS鸿蒙开发知识点,真正体系化!**
由于文件比较大,这里只是将部门目录大纲截图出来,每个节点内里都包含大厂面经、学习笔记、源码讲义、实战项目、解说视频,而且会持续更新
如果你觉得这些内容对你有帮助,可以添加VX:vip204888 (备注鸿蒙获取)
[外链图片转存中…(img-hZCG60AS-1712658163515)]
一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感爱好的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、口试辅导),让我们一起学习成长!
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |