HarmonyOS鸿蒙开发 应用开发常见问题总结(持续更新...)
HarmonyOS鸿蒙开发 应用开发常见问题总结(持续更新…)
在学习鸿蒙开发过程中,也是遇到了不少问题,在代码编写过程中,遇到了一些问题,由于是学习阶段,需要时刻记录一下。
If a component attribute supports local initialization, a valid, runtime-independent default value should be set for it.
意思:如果组件属性支持本地初始化,则应为其设置有效的、独立于运行时的默认值。
- 解决需要为属性设置默认值
原代码:
@ComponentV2
export struct CustomErrorComp {
@Param @Require dataSetConfig: CustomDataSetConfig;
build() {
Column() {
// 设置icon、title、message等元素
CustomDataSetBuilder(this.dataSetConfig)
}
.justifyContent(FlexAlign.Center)
.width('100%')
.height('100%')
.backgroundColor($r('app.color.white'))
}
}
由于传入的参数dataSetConfig,未设置默认值,这里CustomDataSetConfig是一个interface,
传入默认值代码更改后:
@Param @Require dataSetConfig: CustomDataSetConfig = {
title: "",
message: "",
btnTitle: "",
}
...
其他不变
E [ArkRuntime Log] TypeError: is not callable
由于自定义类的interface中有onCallback?: () => void
处理点击回调
源代码中的判断有问题,源代码:
.onClick(()=> {
if (this.dataSetConfig.onCallback !== null) {
this.dataSetConfig.onCallback!();
}
})
一开始以为和flutter判断一样!== null,结果这样判断不对
将代码修改如下就正常了:
.onClick(()=> {
if (this.dataSetConfig.onCallback) {
this.dataSetConfig.onCallback!();
}
})
E [ArkRuntime Log] TypeError: Cannot read property length of undefined
无法读取未定义的属性长度
这里未判断,获取了string的length
所以在使用length前需要做一下typeof this.message !== 'undefined'
判断
// message
if (this.message !== null && typeof this.message !== 'undefined') {
Text(this.message)
.fontSize(12)
.fontColor(Color.red)
.margin({
bottom: this.message.length > 0 ? 10 : 0
})
}
Navigation push之后底部Tabbar 没有隐藏问题
参考https://developer.huawei.com/consumer/cn/doc/architecture-guides/develop-arkui-67-0000002122758974
这里希望可以使用自定义导航栏,根据页面index去切换不同的导航栏,或者隐藏导航栏,思路如下:
修改
通过Navigation嵌套tab,将其隐藏的方式,代码如下
@Entry
@ComponentV2
struct Index {
@Local message: string = 'Hello World';
@Provider('tabCurrentIndex') tabCurrentIndex: number = 0;
// 初始化NavPathStack
@Provider('pageInfos') pageInfos: NavPathStack = new NavPathStack()
使用Navigation嵌套tab
Navigation(this.pageInfos){
Tabs({index: this.tabCurrentIndex, barPosition:BarPosition.End}){
TabContent(){
NewsTabsView()
}
.tabBar(this.TabBuilder({
title: "首页",
targetIndex: 0,
normalImg: $r('app.media.ic_tab_shouye'),
selectedImg: $r('app.media.ic_tab_shouye_filled')
}))
}
.barMode(BarMode.Fixed) // 默认值
.scrollable(false) // 限制滑动
.onAnimationStart((_index: number, targetIndex: number, _event: TabsAnimationEvent) => {
this.tabCurrentIndex = targetIndex;
})
}
.hideTitleBar(true)
跳转使用代码
.onClick(() => {
this.pageInfos.pushPathByName("setting", null, true);
})
The buildFunction ‘PageSettingBuilder’ configured in the routerMap json file does not exist.
配置route_map时候,指定了buildFunction,
route_map如下
{
"routerMap": [
{
"name": "setting",
"pageSourceFile": "src/main/ets/pages/pages/SettingIndexPage.ets",
"buildFunction": "PageSettingBuilder",
"data": {
"description": "this is setting page"
}
}
]
}
所以如果没有在SettingIndexPage.ets页面中创建PageSettingBuilder,则会出现报错
所以在页面增加一个
/// 设置页面
/// 跳转页面入口函数
@Builder
export function PageSettingBuilder() {
SettingIndexPage()
}
@ComponentV2
export struct SettingIndexPage {
// 其他代码
}
Error message:is not callable
在我的代码中,为navigation添加
我的代码如下
@Consumer('pageInfos') pageInfos: NavPathStack = new NavPathStack()
NavDestination() {
List({ space: 12 }) {
ForEach(this.data, (item: PageInfo) => {
ListItem() {
Text("Page" + item.title)
.onClick(() => {
this.pageInfos.pushPathByName("setting", null, true);
})
}
}, (item: PageInfo) => item.url.toString())
}
.width("90%")
.margin({ top: 12 })
}
.title("我的")
.mode(NavDestinationMode.STANDARD)
.onReady((context: NavDestinationContext) => {
this.pageInfos = context.pathStack
})
将onReady去掉即可,没有报错了,暂时有点奇怪,还不清楚原因,学习中
@Consumer('pageInfos') pageInfos: NavPathStack = new NavPathStack()
NavDestination() {
List({ space: 12 }) {
ForEach(this.data, (item: PageInfo) => {
ListItem() {
Text("Page" + item.title)
.onClick(() => {
this.pageInfos.pushPathByName("setting", null, true);
})
}
}, (item: PageInfo) => item.url.toString())
}
.width("90%")
.margin({ top: 12 })
}
.title("我的")
Navigation页面跳转如何传参数
Navigation中,可以使用this.pageInfos.pushPathByName("setting", param, true);
进行页面跳转,
当然在开发中,跳转页面很多时候需要传递参数,传递参数,可以定义interface
我的使用方式如下
export interface SettingPageParam<T> {
from:string,
tag:string
data: T
}
// 进行跳转
let param: SettingPageParam<string> = {
from: "my",
tag: "mytag",
data: "来自我的tab的参数"
};
this.pageInfos.pushPathByName("setting", param, true);
接收参数,需要通过NavPathStack的getParamByName
aboutToAppear(): void {
let param:SettingPageParam<string> = this.pageInfos.getParamByName('setting')[0] as SettingPageParam<string>;
console.info("SettingIndexPage aboutToAppear param.from:"+ param.from + ", param.tag:"+ param.tag + ", param.data:"+ param.data);
}
// 打印的结果
01-02 16:38:03.633 25140-25140 A03d00/JSAPP com.example.myhmapp I SettingIndexPage aboutToAppear param.from:my, param.tag:mytag, param.data:来自我的tab的参数