DEV Community

Cover image for Dialog Controller, ArkUI-X, Marquee, Light/Dark Mode, Global Popup Callback
kouwei qing
kouwei qing

Posted on

Dialog Controller, ArkUI-X, Marquee, Light/Dark Mode, Global Popup Callback

[Daily Harmony Learnings on HarmonyOS Next] Dialog Controller, ArkUI-X, Marquee, Light/Dark Mode, Global Popup Callback

1. Why is HarmonyOS CustomDialogController always undefined?

@Component
export struct DialogBug {
  dialogController: CustomDialogController = new CustomDialogController({
    builder: getPublishWidgetBuilder().builder,
    cornerRadius: 0,
    customStyle: true,
    alignment: DialogAlignment.Center,
    maskColor: 0x77000000
  })

  build() {
    Column() {
      Button('open')
        .onClick(() => {
          this.dialogController.open()
        })
    }
    .margin({ top: 200 })
  }
}

function getPublishWidgetBuilder(): WrappedBuilder<[]> {
  return wrapBuilder(DialogBuilder)
}

@Builder
function DialogBuilder() {
  Mydialog()
}

@Component
@CustomDialog
struct Mydialog {
  dialogController?: CustomDialogController

  build() {
    Column() {
      Button('close')
        .onClick(() => {
          this.dialogController?.close()
        })
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Supplementary Note: Using new CustomDialogController in Mydialog still fails to close the dialog.

Refer to the following modifications:

@Entry
@Component
struct Test5 {
  build() {
    Column() {
      DialogBug()
    }
  }
}

@Component
export struct DialogBug {
  dialogController: CustomDialogController = new CustomDialogController({
    builder: Mydialog(), // Directly use the component instead of wrapBuilder
    cornerRadius: 0,
    customStyle: true,
    alignment: DialogAlignment.Center,
    maskColor: 0x77000000
  })

  build() {
    Column() {
      Button('open').onClick(() => {
        this.dialogController.open()
      })
    }
    .margin({ top: 200 })
  }
}

function getPublishWidgetBuilder(): WrappedBuilder<[]> {
  return wrapBuilder(DialogBuilder)
}

@Builder
function DialogBuilder() {
  Mydialog()
}

@Component
@CustomDialog
struct Mydialog {
  dialogController?: CustomDialogController

  build() {
    Column() {
      Button('close').onClick(() => {
        if (this.dialogController !== undefined) {
          this.dialogController.close()
        }
        console.info('dialogController is undefined')
      })
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

2. What are the advantages and disadvantages of HarmonyOS ArkUI-X compared to other cross-platform frameworks like React Native, Flutter, and Taro?

Advantages:

  1. Development paradigm aligns with HarmonyOS, requiring no extra framework learning.
  2. Cross-platform and cross-device compatibility.
  3. Dynamism (core libraries, dynamic bundles).

3. Can HarmonyOS marquee and font adaptive sizing coexist?

build() {
  Row() {
    Column() {
      Text('一二三四')
        .width('250px')
        .height('50px')
        .maxFontSize('50px')
        .minFontSize('30px')
        .maxLines(1)
        .fontWeight(FontWeight.Bold)
        .fontColor(Color.Gray)
        .textAlign(TextAlign.Center)
        .margin({ top: '30px' })
        .textOverflow({ overflow: TextOverflow.MARQUEE })
    }
    .width('100%')
    .height('100%')
  }
}
Enter fullscreen mode Exit fullscreen mode

Conclusion: Marquee and font adaptive sizing cannot coexist.

Reference: https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-basic-components-text

4. Does the HarmonyOS "Hello World" demo not follow the system light/dark mode?

Add the following line in onCreate:

this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET)

5. Example of globally custom popups with callback functions in HarmonyOS

// CustomDialog_Globally.ets
import { BusinessError } from '@ohos.base';
// CustomDialog_Globally_other01.ets
import { ComponentContent } from '@kit.ArkUI';
import { buildText, Params } from './CustomDialog_Globally';

export class Params {
  text: string = "";
  callback: (volumeType: string, value: number) => void = () => {};

  constructor(text: string, callback: (volumeType: string, value: number) => void) {
    this.text = text;
    this.callback = callback;
  }
}

@Builder
export function buildText(params: Params) {
  // Popup content
  Column() {
    Text(params.text)
      .fontSize(50)
      .fontWeight(FontWeight.Bold)
      .margin({ bottom: 36 })
    Button("Login")
      .onClick(() => {
        params.text = 'Login button clicked';
        // Login result callback
        params.callback('1', 2);
      })
  }.backgroundColor(Color.Yellow);
}


@Entry
@Component
struct CustomDialog_Globally {
  @State message: string = "hello";

  build() {
    Row() {
      Column() {
        Button("Click Me")
          .onClick(() => {
            const uiContext = this.getUIContext();
            const promptAction = uiContext.getPromptAction();
            try {
              const contentNode = new ComponentContent(
                uiContext,
                wrapBuilder(buildText),
                new Params(this.message, (type, val) => {
                  console.log(`Callback: type=${type}, value=${val}`);
                })
              );
              promptAction.openCustomDialog(contentNode);
            } catch (error) {
              const code = (error as BusinessError).code;
              console.error(`OpenCustomDialog error code: ${code}`);
            }
          })
      }
      .width('100%')
      .height('100%')
    }
    .height('100%');
  }
}


@Entry
@Component
struct CustomDialog_Globally_other01 {
  @State message: string = 'Hello World';

  build() {
    Column() {
      Text(this.message)
        .id('HelloWorld')
        .fontSize(50)
        .fontWeight(FontWeight.Bold)
        .onClick(() => {
          const uiContext = this.getUIContext();
          const promptAction = uiContext.getPromptAction();
          const callback = (volumeType: string, value: number) => {
            console.log(`Result: type=${volumeType}, value=${value}`);
            this.message = volumeType;
          };
          const contentNode = new ComponentContent(
            uiContext,
            wrapBuilder(buildText),
            new Params(this.message, callback)
          );
          try {
            promptAction.openCustomDialog(contentNode);
          } catch (error) {
            const msg = (error as BusinessError).message;
            const code = (error as BusinessError).code;
            console.error(`Error: code=${code}, message=${msg}`);
          }
        })
    }
    .height('100%')
    .width('100%');
  }
}
Enter fullscreen mode Exit fullscreen mode

Top comments (0)