【Daily HarmonyOS Next Knowledge】Pixel Unit Conversion, Dialog Declaration Issues, List Nesting, Byte Stream to Image, Builder Function State Not Triggering UI Changes
1. Which pixel unit should be used in HarmonyOS?
The UI provides an image with 750 pixels. When developing, for a button with a width of 100px/100dp, should we use px2vp(100)
, 100/2 = 50vp
, or another approach?
For specific conversion between vp and px, refer to: https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/ts-pixel-units-V5#%E5%83%8F%E7%B4%A0%E5%8D%95%E4%BD%8D%E8%BD%AC%E6%8D%A2
Interface | Description |
---|---|
vp2px(value: number): number |
Converts a value in vp units to px units. Note: Uses the virtual pixel ratio of the current UI instance's screen by default. If the UI instance is not created, uses the default screen's virtual pixel ratio. |
px2vp(value: number): number |
Converts a value in px units to vp units. Note: Uses the virtual pixel ratio of the current UI instance's screen by default. If the UI instance is not created, uses the default screen's virtual pixel ratio. |
fp2px(value: number): number |
Converts a value in fp units to px units. |
px2fp(value: number): number |
Converts a value in px units to fp units. |
lpx2px(value: number): number |
Converts a value in lpx units to px units. |
px2lpx(value: number): number |
Converts a value in px units to lpx units. |
2. Why can't CustomDialogController be declared outside a Component in HarmonyOS?
I want to create a project-wide LoadingDialog for convenient calling, such as globalDialogController.show()
.
The custom dialog CustomDialogController
is only valid when used as a member variable of @CustomDialog
and @Component
structs and assigned within the @Component
struct. Use promptAction.openCustomDialog
for dialog rendering instead of CustomDialogController
.
Reference: https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/js-apis-promptaction-V5
3. Can the HarmonyOS List component not be nested with the Grid component?
Rendering Grid components within ListItem of the List component is invalid.
Sample code for testing:
@Entry
@Component
struct Index6 {
build() {
Row() {
Column() {
List() {
ListItem() {
Text("I am a ListItem")
}.height(200)
ListItem() {
Grid() {
ForEach([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], (item: number) => {
GridItem() {
Column() {
Text(`number:${item}`)
}
.backgroundColor(`#87${item}`)
}
})
}
.rowsTemplate('1fr 1fr 1fr 1fr 1fr')
.columnsTemplate('1fr 1fr 1fr 1fr 1fr')
.rowsGap(30)
.columnsGap(20)
.backgroundColor("#987")
}.height(200)
}
}
.width('100%')
}
.height('100%')
}
}
4. How to display image data in byte[] format in an Image component in HarmonyOS?
Convert the buffer to a PixelMap and then load it. Example:
let imageSource = image.createImageSource(buffer)
let options = {
alphaType: 0, // Transparency
editable: false, // Editable status
pixelFormat: 3, // Pixel format
scaleMode: 1, // Scaling mode
size: { height: 100, width: 100 } // Created image size
}
imageSource.createPixelMap(options).then((pixelMap) => {
this.image = pixelMap
})
5. Why doesn't the state variable received by a HarmonyOS @builder function trigger internal UI changes?
The ChangePinPage interface invokes a custom keyboard. Modifying currentKeyboardType
(keyboard type) in the custom keyboard's button component to switch between Chinese and English keyboards does not update the value of Text($\{$$.currentKeyboardType})
in CustomKeyboard.ets.
// xxxModel.ets
export class Tmp {
inputController: TextInputController;
currentKeyboardType: number;
constructor(inputController: TextInputController, currentKeyboardType: number) {
this.inputController = inputController;
this.currentKeyboardType = currentKeyboardType
}
}
# ChangePinPage.ets:
@Provide currentKeyboardType: number = Const.KEYBOARD_TYPE_NUMBER;
...
TextInput()
.customKeyboard(KeyBoardWindow(new Tmp(this.oldPinController, this.currentKeyboardType)))
# CustomKeyboard.ets:
@Builder
export function KeyBoardWindow($$: Tmp) {
Column() {
Row() {
Image($r("app.media.ic_keyboard_down"))// "Collapse" icon in the title row
.onClick(() => {
$$.inputController.stopEditing()
})
Text(`${$$.currentKeyboardType}`)
}
}
// xxxChild.ets ...
@Consume currentKeyboardType: number;
...
this.currentKeyboardType = 2;
For global @builder custom build functions using reference passing, if placed within Navigation()'s menus, state variable changes will not trigger UI refresh in the @builder method.
When passing parameters by reference, the parameters can be state variables, and state variable changes will trigger UI refresh in the @builder method.
Reference: https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/arkts-builder-V5
Related demo:
@Builder function ABuilder($$: { paramA1: string }) {
Row() {
Text(`UseStateVarByReference: ${$$.paramA1} `)
}
}
@Entry
@Component
struct Parent {
@State label: string = 'Hello';
build() {
Column() {
// When calling ABuilder in the Parent component, pass this.label by reference to ABuilder
ABuilder({ paramA1: this.label })
Button('Click me').onClick(() => {
// After clicking "Click me", the UI refreshes from "Hello" to "ArkUI"
this.label = 'ArkUI';
})
}
}
}
Top comments (0)