【Daily HarmonyOS Next Knowledge】Component Offset, Popup Arrow Color & Bubble Radius, Dynamic Attributes, Scan UI Implementation
1. HarmonyOS popup component offset after page content switching?
interface dataItem {
title: string;
price: number;
price2: number;
}
@Entry
@Component
struct Index {
@State dataSource: Array<dataItem> = [
{ title: 'AAAAAA', price: 100, price2: 111 },
{ title: 'BBBBBB', price: 299, price2: 398 }
];
@State index: number = 0;
@State qty: number = 0;
@State qty2: number = 0;
@State total: number = 0;
@State total2: number = 0;
@State showModal: boolean = false;
@State showPopup: boolean = false;
@State showPopup2: boolean = false;
handleClick(type: string) {
if (type === 'minus' && this.qty > 0) {
this.qty -= 1;
this.total = this.qty * this.dataSource[this.index].price;
this.showPopup = this.qty > 0;
} else if (type === 'add') {
this.qty += 1;
this.total = this.qty * this.dataSource[this.index].price;
this.showPopup = this.qty > 0;
}
}
handleClick2(type: string) {
if (type === 'minus' && this.qty2 > 0) {
this.qty2 -= 1;
this.total2 = this.qty2 * this.dataSource[this.index].price2;
this.showPopup2 = this.qty2 > 0;
} else if (type === 'add') {
this.qty2 += 1;
this.total2 = this.qty2 * this.dataSource[this.index].price2;
this.showPopup2 = this.qty2 > 0;
}
}
@Builder
modalBuilder() {
Column() {
ForEach(this.dataSource, (item: dataItem, index: number) => {
Text(item.title)
.width('90%')
.height(50)
.textAlign(TextAlign.Center)
.border({ width: 1 })
.margin({ bottom: 10 })
.onClick(() => {
this.index = index;
this.total = this.qty * this.dataSource[this.index].price;
this.total2 = this.qty2 * this.dataSource[this.index].price2;
this.showModal = false;
})
}, (item: dataItem, index: number) => {
return item.title;
})
}
.padding({ top: 100 })
.width('100%')
.height('100%')
.backgroundColor(Color.White)
}
@Builder
popupBuilder(type: number) {
Column() {
Text(String(type === 1 ? this.total : this.total2))
.fontSize(11)
.fontColor(Color.White)
.padding({
top: 1,
bottom: 1,
left: 12,
right: 12
})
.backgroundColor(Color.Black)
}
}
build() {
Column() {
Row() {
Text(this.dataSource[this.index].title)
}
.height(50)
.width('90%')
.justifyContent(FlexAlign.Center)
.border({ width: 1 })
.bindSheet(this.showModal, this.modalBuilder(), {
height: 300,
dragBar: false
})
.onClick(() => {
this.showModal = !this.showModal;
})
Column() {
Row() {
Text('-')
.width(30)
.height(30)
.backgroundColor(Color.Red)
.fontColor(Color.White)
.textAlign(TextAlign.Center)
.onClick(() => this.handleClick('minus'))
Text(String(this.total))
.height(30)
.border({ width: 1, color: Color.Red })
.width(60)
.textAlign(TextAlign.Center)
Text('+')
.width(30)
.height(30)
.backgroundColor(Color.Red)
.fontColor(Color.White)
.textAlign(TextAlign.Center)
.onClick(() => this.handleClick('add'))
}
.margin({ bottom: 20 })
.bindPopup(this.showPopup, {
builder: this.popupBuilder(1),
popupColor: Color.Black,
placement: Placement.Top,
autoCancel: false,
radius: 1,
mask: false,
arrowWidth: 8,
arrowHeight: 6,
shadow: ShadowStyle.OUTER_DEFAULT_XS
})
Row() {
Text('-')
.width(30)
.height(30)
.backgroundColor(Color.Red)
.fontColor(Color.White)
.textAlign(TextAlign.Center)
.onClick(() => this.handleClick2('minus'))
Text(String(this.total2))
.height(30)
.border({ width: 1, color: Color.Red })
.width(60)
.textAlign(TextAlign.Center)
Text('+')
.width(30)
.height(30)
.backgroundColor(Color.Red)
.fontColor(Color.White)
.textAlign(TextAlign.Center)
.onClick(() => this.handleClick2('add'))
}
.bindPopup(this.showPopup2, {
builder: this.popupBuilder(2),
popupColor: Color.Black,
placement: Placement.Top,
autoCancel: false,
radius: 1,
mask: false,
arrowWidth: 8,
arrowHeight: 6,
shadow: ShadowStyle.OUTER_DEFAULT_XS
})
}
.alignItems(HorizontalAlign.Start)
.width('100%')
.padding(20)
}
.width('100%')
.height('100%')
.padding({ top: 50 })
}
}
2. How to set arrow color and bubble content radius when using HarmonyOS bindPopup?
-
radius: '10vp'
// Set bubble corner radius -
backgroundBlurStyle: BlurStyle.NONE
// Set arrow color, associated with thepopupColor
attribute
Demo reference:
@Entry
@Component
struct BindPopupDemo {
@State customPopup: boolean = false;
@Builder
popupBuilder() {
Column({ space: 2 }) {
Row().width(64)
.height(64)
.backgroundColor(0x409eff)
Text('Popup')
.fontSize(10)
.fontColor(Color.White)
}
.justifyContent(FlexAlign.SpaceAround)
.width(100)
.height(100)
.padding(5)
}
@Builder
customBubbleInstructionBuilder() {
Stack() {
Text() {
Span("2021年12月20日-2022月1日30日每人限购8件 已购买3件,还可购5件").fontSize(12)
Span(" 已购买3件,还可购5件").fontSize(14)
}.fontColor(Color.White)
.maxLines(2).textOverflow({ overflow: TextOverflow.Ellipsis }).ellipsisMode(EllipsisMode.END)
}.backgroundColor(0x409eff)
.width(100)
.padding({
left: 12,
right: 12,
top: 18,
bottom: 8
})
}
build() {
Column() {
Button('click')
.onClick(() => {
this.customPopup = !this.customPopup;
})
.backgroundColor(0xf56c6c)
.bindPopup(this.customPopup, {
builder: this.customBubbleInstructionBuilder,
placement: Placement.Top,
maskColor: 0x33000000,
popupColor: 0xf56c6c,
enableArrow: true,
radius: '10vp',
backgroundBlurStyle: BlurStyle.NONE,
onStateChange: (e) => {
if (!e.isVisible) {
this.customPopup = false;
}
}
})
}
.justifyContent(FlexAlign.Center)
.width('100%')
.height(437)
}
}
3. Usage of HarmonyOS NativeXComponent?
Reference document: https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/_o_h___native_x_component-V5
Native XComponent describes the surface and touch events held by ArkUI XComponent, which can be used for EGL/OpenGLES and media data input, and displayed on ArkUI XComponent.
4. HarmonyOS new TextAttribute() causes a crash with the error "TextAttribute is not defined"?
@Component
export struct IconFontView {
@Prop content: string | null = null;
@Prop iconModifier: TextAttribute = new TextAttribute();
private textModifier: TextModifier = new TextModifier(this.iconModifier);
The above code compiles successfully but errors at runtime.
Incorrect usage of TextAttribute. Modify as follows (refer to documentation for usage):
Document link: https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/ts-universal-attributes-attribute-modifier-V5
Refer to the usage of buttonAttribute:
class MyButtonModifier implements AttributeModifier<ButtonAttribute> {
isDark: boolean = false
applyNormalAttribute(instance: ButtonAttribute): void {
if (this.isDark) {
instance.backgroundColor(Color.Black)
} else {
instance.backgroundColor(Color.Red)
}
}
}
@Entry
@Component
struct attributeDemo {
@State modifier: MyButtonModifier = new MyButtonModifier()
build() {
Row() {
Column() {
Button("Button")
.attributeModifier(this.modifier)
.onClick(() => {
this.modifier.isDark = !this.modifier.isDark
})
}
.width('100%')
}
.height('100%')
}
}
5. How to implement HarmonyOS ArkTS scan UI?
@Entry
@Component
struct Page240419172038091_bak {
private settings: RenderingContextSettings = new RenderingContextSettings(true)
private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)
private screenCenterX: number = 0
private screenCenterY: number = 0
@State sCanLineY: number = 0
build() {
Stack({ alignContent: Alignment.Center }) {
Image($r("app.media.bg")).width(200)
Canvas(this.context).width("100%").height("100%").backgroundColor(Color.Transparent).onReady(() => {
let canvasWidth = this.context.width
let canvasHeight = this.context.height
this.screenCenterX = canvasWidth / 2
this.screenCenterY = canvasHeight / 2
this.context.fillStyle = "#80000000"
this.context.beginPath()
this.context.moveTo(0, 0)
this.context.lineTo(0, this.context.height)
this.context.lineTo(this.context.width, this.context.height)
this.context.lineTo(this.context.width, 0)
this.context.lineTo(0, 0)
this.context.fill()
this.context.clearRect(this.screenCenterX - 100, this.screenCenterY - 100, 200, 200)
this.context.beginPath();
this.context.moveTo(this.screenCenterX, this.screenCenterY)
this.context.fillStyle = "#802ac327";
this.context.fillRect(this.screenCenterX - 100, this.screenCenterY - 100, 200, 2)
setInterval(() => {
this.context.clearRect(this.screenCenterX - 100, this.screenCenterY - 100, 200, 200)
if (this.sCanLineY > 197) {
this.sCanLineY = 0
} else {
this.sCanLineY++
}
this.context.fillRect(this.screenCenterX - 100, this.screenCenterY - 100 + this.sCanLineY, 200, 2)
}, 8)
})
}.width("100%").height("100%")
}
}
Top comments (0)