DEV Community

Cover image for Flex Component, List Refresh, Custom Pop-up, Button States, Auto Soft Keyboard Pop-up
kouwei qing
kouwei qing

Posted on

Flex Component, List Refresh, Custom Pop-up, Button States, Auto Soft Keyboard Pop-up

[Daily HarmonyOS Next Knowledge] Flex Component, List Refresh, Custom Pop-up, Button States, Auto Soft Keyboard Pop-up

1. Issues with HarmonyOS Flex component causing incorrect UI?

The expected effect is that the first child1 Flex should not fill the entire main axis.

Flex({
  direction: FlexDirection.Column,
  // wrap: FlexWrap.NoWrap,
  // justifyContent:  FlexAlign.Center,
  // alignItems: ItemAlign.Start,
  // alignContent: FlexAlign.Start,
}){
  Flex({
    direction: FlexDirection.Column,
    // wrap: FlexWrap.NoWrap,
    // justifyContent: FlexAlign.Start,
    // alignItems: ItemAlign.Start,
    // alignContent: FlexAlign.Start,
  }) {
    Text("啊是打火机卡的黑科技abc1234567890")
  }.id("child1")
  Text("啊是打火机卡的黑科技")
}

Code 2:
  Flex({
    direction: FlexDirection.Column,
    // wrap: FlexWrap.NoWrap,
    // justifyContent:  FlexAlign.Center,
    // alignItems: ItemAlign.Start,
    // alignContent: FlexAlign.Start,
  }){
    Flex({
      direction: FlexDirection.Column,
      // wrap: FlexWrap.NoWrap,
      // justifyContent: FlexAlign.Start,
      // alignItems: ItemAlign.Start,
      // alignContent: FlexAlign.Start,
    }) {
      Text("啊是打火机卡的黑科技abc1234567890")
        .flexBasis(0).flexShrink(1).flexGrow(0)
    }.flexBasis(0).flexShrink(1).flexGrow(0).id("child1")
    Text("啊是打火机卡的黑科技")
  }
Enter fullscreen mode Exit fullscreen mode

By default, the Flex component's main axis fills the parent container when not explicitly set, while the Column/Row component's main axis follows the child nodes' sizes by default.

2. How to refresh a List when ListItem data in HarmonyOS ListItemGroup is updated?

Abstract the group data into a component and pass the required parameters. Code:

@Observed
class ProjectArray extends Array<string>{
}

@Observed
class Subject {
  public title: string;
  public projects: ProjectArray;
  constructor(title, projects) {
    this.title = title;
    this.projects = projects;
  }
}

@Component
struct ViewA {
  title: string;
  @ObjectLink projects: ProjectArray;
  build() {
    Column() {
      Text(this.title)
      List(){
        ForEach(this.projects, (project) => {
          ListItem() {
            Text(project)
              .width("100%").height(100).fontSize(20)
              .textAlign(TextAlign.Center).backgroundColor(0xFFFFFF)
          }

        })
      }
    }
  }
}

@Entry
@Component
struct ListItemGroupExample2 {
  @State timetable: Subject[] = [
    new Subject('星期一', new ProjectArray('语文', '数学', '英语'))
  ]
  build() {
    Column() {
      Button('change')
        .onClick(() => {
          console.log('testTag: Change');
          this.timetable[0].projects.splice(0, 1, '英语');
        })
      ForEach(this.timetable, (table) => {
        ViewA({title: table.title, projects: table.projects})
      })

    }.width('100%').height('100%').backgroundColor(0xDCDCDC).padding({ top: 20 })
  }
}
Enter fullscreen mode Exit fullscreen mode

3. How to display a @Builder-decorated function in the description of a HarmonyOS custom dialog?

Refer to the following demo:

@Builder
function customDialogBuilder(price:string,id_no:string) {
  Column({space:15}) {
    Row() {
      Text('运费:' + price)
        .fontSize(10)
    }
    Row() {
      Text('货单:' + id_no)
        .fontSize(10)
    }
  }
  .width('100%')
  .height(200)
  .padding(5)
  .backgroundColor("#FF0000")
}

@CustomDialog
struct CustomDialogExample {
  @Link title: string
  @Link price: string
  @Link id_no: string
  controller?: CustomDialogController
  cancel: () => void = () => {
  }
  confirm: () => void = () => {
  }

  build() {
    Column() {
      Text(this.title).fontSize(20).margin({ top: 10, bottom: 10 })
      customDialogBuilder(this.price,this.id_no)
      Flex({ justifyContent: FlexAlign.SpaceAround }) {
        Button('cancel')
          .onClick(() => {
            if (this.controller != undefined) {
              this.controller.close()
              this.cancel()
            }
          }).backgroundColor(0xffffff).fontColor(Color.Black)
        Button('confirm')
          .onClick(() => {
            if (this.controller != undefined) {
              this.controller.close()
              this.confirm()
            }
          }).backgroundColor(0xffffff).fontColor(Color.Red)
      }.margin({ bottom: 10 })
    }.borderRadius(10)
  }
}

@Entry
@Component
struct Index {

  @State title: string = ''
  @State price: string = ''
  @State id_no: string = ''
  dialogController: CustomDialogController | null = new CustomDialogController({
    builder: CustomDialogExample({
      cancel: () => {
        this.onCancel()
      },
      confirm: () => {
        this.onAccept()
      },
      title: $title,
      price: $price,
      id_no: $id_no,
    }),
    autoCancel: true,
    alignment: DialogAlignment.Bottom,
    offset: { dx: 0, dy: -20 },
    gridCount: 4,
    customStyle: false,
    cornerRadius: 10,
  })

  // Set dialogControlle to null when the custom component is about to be destroyed
  aboutToDisappear() {
    this.dialogController = null // Set dialogController to null
  }

  onCancel() {
    console.info('Callback when the first button is clicked')
  }

  onAccept() {
    console.info('Callback when the second button is clicked')
  }

  build() {
    Row() {
      Column() {
        Button('自定义弹框')
          .width('100vp')
          .height('100vp')
          .onClick(() => {
            if (this.dialogController != null) {
              this.title = '自定义弹框title'
              this.price = '100元'
              this.id_no = '1234567895549'
              this.dialogController.open()
            }
          })
      }
      .width('100%')
    }
    .height('100%')
  }
}
Enter fullscreen mode Exit fullscreen mode

4. How to set images for normal and selected states of a HarmonyOS button?

Set one image for the normal state and another for the selected state.

Refer to the demo:

@Entry
@Component
struct Page240605153407040 {
  @State message: string = 'app.media.photo';

  build() {
    Row() {
      Column() {
        Button() {
          Image($r(this.message))
        }
        .width(40).height(40).margin({ left: 18 })
        .onClick(()=>{
          if (this.message == 'app.media.photo' ) {
            this.message = 'app.media.startIcon'
          }else {
            this.message = 'app.media.photo'
          }

        })
      }
      .width('100%')
    }
    .height('100%')
  }
}
Enter fullscreen mode Exit fullscreen mode

5. How to automatically pop up the soft keyboard after opening a page in HarmonyOS?

Use focusControl.requestFocus to control the input box's focus. The soft keyboard will automatically pop up when the component gains focus.

The TextInput triggers the input method when focused and closes it when focus is lost. Use focusControl to manage focus for closing the soft keyboard.

build() {
  Column() {
    TextInput()
    Button(`hide`)
      .key('button')
      .onClick(()=>{
        focusControl.requestFocus('button')
      })
  }
}
Enter fullscreen mode Exit fullscreen mode

Judge by listening to the keyboard height change event:

window.getLastWindow(context).then(lastWindow => {
  lastWindow.on('keyboardHeightChange', (size: number) => {
    console.warn(`...keyboardHeightChange: ${size}`);
  })
}).catch((err: BusinessError) => {console.error(`...error message: ${err.message}`);
})
Enter fullscreen mode Exit fullscreen mode

Top comments (0)