【每日学点HarmonyOS Next知识】重叠顺序、对话框位置、事件总线、PageMap显示、多表多item类型
1、HarmonyOS WebView 布局带输入框,底部文案被顶起 布局重叠?
WebView设置层级显示可以通过z序控制来实现,参考链接:https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/ts-universal-attributes-z-order-V5
zIndex
zIndex(value: number)
设置组件的堆叠顺序。
参数:
参数名 | 类型 | 必填 | 说明 |
---|---|---|---|
value | number | 是 | 同一容器中兄弟组件显示层级关系。zIndex值越大,显示层级越高,即zIndex值大的组件会覆盖在zIndex值小的组件上方。当不涉及新增或减少兄弟节点,动态改变zIndex时会在zIndex改变前层级顺序的基础上进行稳定排序。 |
示例(设置组件堆叠顺序)
// xxx.ets
@Entry
@Component
struct ZIndexExample {
build() {
Column() {
Stack() {
// stack会重叠组件, 默认后定义的在最上面,具有较高zIndex值的元素在zIndex较小的元素前面
Text('1, zIndex(2)')
.size({ width: '40%', height: '30%' }).backgroundColor(0xbbb2cb)
.zIndex(2)
Text('2, default zIndex(1)')
.size({ width: '70%', height: '50%' }).backgroundColor(0xd2cab3).align(Alignment.TopStart)
.zIndex(1)
Text('3, zIndex(0)')
.size({ width: '90%', height: '80%' }).backgroundColor(0xc1cbac).align(Alignment.TopStart)
}.width('100%').height(200)
}.width('100%').height(200)
}
}
2、HarmonyOS 自定义 Dialog 居于页面底部,弹出的软键盘和 dialog 有很大间隙?
参考代码:
import window from '@ohos.window'
import { data } from '@kit.TelephonyKit'
@Entry
@Component
export struct LightPublishMine {
private window?: window.Window
@State keyboardHeightVp: number = 0
@State navHeight: number = 0
@State safeAreaTop: number = 0
aboutToAppear() {
window.getLastWindow(getContext(this)).then((win) => {
this.window = win
if (this.window) {
this.navHeight = px2vp(this.window.getWindowAvoidArea(window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR)
//导航条高度
.bottomRect.height
)
this.safeAreaTop = px2vp(this.window.getWindowAvoidArea(window.AvoidAreaType.TYPE_SYSTEM).topRect.height)
this.window.on('keyboardHeightChange', (data) => {
console.info('Succeeded in enabling the listener for keyboard height changes. 键盘 Data: ' + data);
this.keyboardHeightVp = px2vp(data)
console.info('Succeeded in enabling the listener for keyboard height changes. Data: ' + (this.keyboardHeightVp - this.navHeight));
console.info('Succeeded in enabling the listener for keyboard height changes. 导航条Data: ' + this.navHeight);
});
}
})
}
aboutToDisappear() {
if (this.window) {
this.window.off('keyboardHeightChange')
this.window = undefined
}
this.keyboardHeightVp = 0
}
build() {
Row() {
Column() {
TextInput().backgroundColor(Color.White)
Blank().backgroundColor(Color.Red).height(this.keyboardHeightVp - this.navHeight).width('100%')
}.width('100%')
}
.height('100%')
.backgroundColor(Color.Green)
.alignItems(VerticalAlign.Bottom)
.expandSafeArea([SafeAreaType.KEYBOARD], [SafeAreaEdge.BOTTOM])
}
}
@Entry
@Component
struct CustomDialogUser {
dialogController: CustomDialogController = new CustomDialogController({
builder: CommentInputDialog({}),
alignment: DialogAlignment.Bottom,
customStyle: true,
offset: { dx: 0, dy: 100 }
})
build() {
Column() {
Button('click me')
.onClick(() => {
this.dialogController.open()
})
}.width('100%').height('100%').backgroundColor(Color.Red)
}
}
可以将customStyle设置为true,并且给弹框内部的Column设置偏移.offset({ x: 0, y: 20})
@CustomDialog
export struct CommentInputDialog{
private statusBarHeight: number = (AppStorage.get('statusBarHeight') as number);
controller?: CustomDialogController
private commentContent: string = ''
onTap: (content: string) => void = () => {
};
build() {
Column(){
Image($r('app.media.black_close_icon'))
.width(26)
.height(26)
.onClick(() =>{
this.controller?.close();
})
TextArea({ placeholder: '我来说两句...', text: this.commentContent})
.placeholderColor($r('app.color.color909099'))
.backgroundColor($r('app.color.colorF7F8F9'))
.borderRadius(4)
.placeholderFont({
size: '17fp',
family: CommonConstants.SI_YUAN
})
.backgroundColor(Color.White)
.enterKeyType(EnterKeyType.Done)
.defaultFocus(true)
.onChange((value) => {
this.commentContent = value;
}).margin({top: 10, bottom: 10})
.layoutWeight(1)
Text('确认')
.width(60)
.height(30)
.fontColor(Color.White)
.fontSize('14fp')
.fontFamily(CommonConstants.SI_YUAN)
.textAlign(TextAlign.Center)
.backgroundColor($r('app.color.colorF21333'))
.borderRadius(15)
.onClick(() =>{
this.onTap(this.commentContent)
})
}
.width(CommonConstants.FULL_PERCENT)
.height(210 + this.statusBarHeight)
.padding({left: 15, top: 15, right: 15, bottom: 10 + this.statusBarHeight })
.alignItems(HorizontalAlign.End)
.backgroundColor($r('app.color.colorF1F2F3'))
.borderRadius({topLeft: 15, topRight: 15})
.offset({ x: 0, y: 20}) // 设置偏移
}
}
3、HarmonyOS ArkTS项目有全局通知的类似vue的事件总线eventbus的方法吗?
调用router.back()方法后,页面不会数据渲染,想要使用事件总线来调用页面数据更新,并且事件总线不与生命周期绑定,只要触发总线方法 任何定义的地方都会被调用,无需在生命周期里才能调用
关于全局通知下面的文档有相关内容
通知服务公共事件定义链接:https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/js-apis-commoneventmanager-V5#commoneventmanagerpublish
通知接口文档链接:https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/js-apis-notificationmanager-V5#notificationmanagerpublish
4、HarmonyOS navDestionation函数中Builder的超过3个不能显示?
使用Navigation,navDestination(this.PageMap),这个PageMap只能显示第一和第二的component,排在第三个位置的页面跳转后显示不出来。
可以尝试一下使用 if(){} else if(){}格式,如下:
@Builder
PagesMap(name: string) {
if (name === 'Page01') {
Page01()
}
else if (name === 'Page02') {
Page02()
}
else if (name === 'Page03') {
Page03()
}
else if (name === 'Page04') {
Page04()
}
}
5、HarmonyOS 一个列表有超过10种以上的item类型,有什么好的分发处理手段吗?
可以尝试表驱动的方法:对于逻辑表达模式固定的 if…else 代码,可以通过某种映射关系,将逻辑表达式用表格的方式表示;再使用表格查找的方式,找到某个输入所对应的处理函数,使用这个处理函数进行运算。
适用场景逻辑表达模式固定的 if…else
实现与示例:
if (param.equals(value1)) {
doAction1(someParams);
} else if (param.equals(value2)) {
doAction2(someParams);
} else if (param.equals(value3)) {
doAction3(someParams);
}
// ...
可重构为
Map<?, Function<?> action> actionMappings = new HashMap<>(); // 这里泛型 ? 是为方便演示,实际可替换为你需要的类型
// When init
actionMappings.put(value1, (someParams) -> { doAction1(someParams)});
actionMappings.put(value2, (someParams) -> { doAction2(someParams)});
actionMappings.put(value3, (someParams) -> { doAction3(someParams)});
// 省略 null 判断
actionMappings.get(param).apply(someParams);